<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Java Code Geeks</title>
    <link>https://www.javacodegeeks.com/feed/</link>
    <description>Java Developers Resource Center</description>
    <pubDate>Wed, 24 Jun 2026 10:15:42 +0000</pubDate>
    <lastBuildDate>Wed, 24 Jun 2026 10:15:42 +0000</lastBuildDate>
    <image>
      <url>https://www.javacodegeeks.com/wp-content/uploads/2012/12/JavaCodeGeeks-favIcon.png</url>
      <title>Java Code Geeks</title>
      <link>https://www.javacodegeeks.com/</link>
    </image>
    <item>
      <title>Top 9 Role-Based Cloud Certifications for Solution Architects in 2026</title>
      <link>https://www.javacodegeeks.com/2026/06/top-9-role-based-cloud-certifications-for-solution-architects-in-2026.html</link>
      <description>&lt;header class=entry-header-outer&gt;&lt;nav id=breadcrumb&gt;&lt;a href=https://www.javacodegeeks.com/&gt;&lt;span class=tie-icon-home aria-hidden=true&gt;&lt;/span&gt;Home&lt;/a&gt;&lt;em class=delimiter&gt;»&lt;/em&gt;&lt;a href=https://www.javacodegeeks.com/category/software-development&gt;Software Development&lt;/a&gt;&lt;em class=delimiter&gt;»&lt;/em&gt;&lt;span class=current&gt;Top 9 Role-Based Cloud Certifications for Solution Architects in 2026&lt;/span&gt;&lt;/nav&gt;&lt;div class=entry-header&gt;&lt;span class=post-cat-wrap&gt;&lt;a class=&#34;post-cat tie-cat-15&#34; href=https://www.javacodegeeks.com/category/software-development&gt;Software Development&lt;/a&gt;&lt;/span&gt;&lt;h1 class=&#34;post-title entry-title&#34;&gt;Top 9 Role-Based Cloud Certifications for Solution Architects in 2026&lt;/h1&gt;&lt;/div&gt;&lt;/header&gt;&lt;div class=&#34;entry-content entry clearfix&#34;&gt;&lt;div class=&#34;stream-item stream-item-above-post-content&#34;&gt;&lt;div class=stream-item-size&gt;&lt;div id=adngin-in-post-0 style=&#34;float:left; margin-right:20px; margin-bottom:10px; width:300px; height:274px;&#34;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p class=wp-block-paragraph&gt;Cloud architecture is no longer a niche specialisation — it is the backbone of how modern enterprises build, scale, and secure everything from mobile apps to AI pipelines. Yet the certification landscape can feel overwhelming. Which badge actually opens doors? Which one pays for itself fastest? This guide cuts through the noise and focuses specifically on role-based credentials that solution architects will find most valuable in 2026.&lt;p class=wp-block-paragraph&gt;Before diving in, it helps to understand why role-based certifications matter more than vendor-neutral fundamentals at this stage of the market. General cloud literacy is increasingly assumed at the hiring level. What employers are looking for now is proof that you can &lt;em&gt;design&lt;/em&gt; systems — not just use them. With that lens in place, let’s walk through the nine certifications worth your attention this year.&lt;p class=&#34;has-text-align-center wp-block-paragraph&#34;&gt;&lt;strong&gt;Average US Salary by Certification (2026, USD)&lt;/strong&gt;&lt;div class=wp-block-image&gt;&lt;figure class=&#34;aligncenter size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-28-46.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-28-46.png fetchpriority=high decoding=async width=510 height=272 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-28-46.png alt class=wp-image-144099 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-28-46.png 510w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-28-46-300x160.png 300w&#34; data-sizes=&#34;(max-width: 510px) 100vw, 510px&#34;&gt;&lt;noscript&gt;&lt;img fetchpriority=high decoding=async width=510 height=272 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-28-46.png alt class=wp-image-144099 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-28-46.png 510w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-28-46-300x160.png 300w&#34; sizes=&#34;(max-width: 510px) 100vw, 510px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p class=&#34;has-text-align-center wp-block-paragraph&#34;&gt;&lt;strong&gt;Exam Cost vs Average Salary Uplift (2026)&lt;/strong&gt;&lt;div class=wp-block-image&gt;&lt;figure class=&#34;aligncenter size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-29-32.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-29-32.png decoding=async width=501 height=248 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-29-32.png alt class=wp-image-144100 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-29-32.png 501w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-29-32-300x149.png 300w&#34; data-sizes=&#34;(max-width: 501px) 100vw, 501px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=501 height=248 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-29-32.png alt class=wp-image-144100 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-29-32.png 501w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-29-32-300x149.png 300w&#34; sizes=&#34;(max-width: 501px) 100vw, 501px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p class=wp-block-paragraph&gt;Now let’s break down each certification in detail — starting with the certifications most architects reach for first, and working toward the specialisations that separate senior practitioners from the crowd.&lt;h3 class=wp-block-heading&gt;1. AWS Certified Solutions Architect – Associate (SAA-C03)&lt;/h3&gt;&lt;div class=wp-block-image&gt;&lt;figure class=&#34;aligncenter size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-30-12.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-30-12.png decoding=async width=498 height=157 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-30-12.png alt class=wp-image-144101 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-30-12.png 498w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-30-12-300x95.png 300w&#34; data-sizes=&#34;(max-width: 498px) 100vw, 498px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=498 height=157 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-30-12.png alt class=wp-image-144101 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-30-12.png 498w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-30-12-300x95.png 300w&#34; sizes=&#34;(max-width: 498px) 100vw, 498px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p class=wp-block-paragraph&gt;If there is one place most architects begin, it is here. The &lt;a href=https://aws.amazon.com/certification/certified-solutions-architect-associate/ target=_blank rel=&#34;noreferrer noopener&#34;&gt;AWS Certified Solutions Architect – Associate (SAA-C03)&lt;/a&gt; is widely recognised as the entry credential for cloud architecture roles. It proves you can design and deploy secure, scalable solutions across core AWS services — compute, storage, databases, networking, and more.&lt;p class=wp-block-paragraph&gt;What makes it particularly valuable is market reach. AWS holds the largest share of the global cloud market, and &lt;a href=https://kodekloud.com/blog/top-five-cloud-certifications-to-pursue-in-2025/ target=_blank rel=&#34;noreferrer noopener&#34;&gt;LinkedIn job data shows over 45,000 AWS cloud engineer openings&lt;/a&gt; at any given time — far ahead of GCP. For most professionals, this is the right first step, even if the goal eventually includes Azure or GCP credentials too.&lt;p class=wp-block-paragraph&gt;The exam itself covers 1–3 years of recommended hands-on experience and is offered at a very accessible price point. From a pure ROI standpoint, it delivers an average salary uplift of around $26,000 — one of the strongest returns on a $150 investment in the certification world.&lt;h3 class=wp-block-heading&gt;2. AWS Certified Solutions Architect – Professional (SAP-C02)&lt;/h3&gt;&lt;div class=wp-block-image&gt;&lt;figure class=&#34;aligncenter size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-32-17.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-32-17.png decoding=async width=496 height=159 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-32-17.png alt class=wp-image-144102 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-32-17.png 496w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-32-17-300x96.png 300w&#34; data-sizes=&#34;(max-width: 496px) 100vw, 496px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=496 height=159 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-32-17.png alt class=wp-image-144102 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-32-17.png 496w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-32-17-300x96.png 300w&#34; sizes=&#34;(max-width: 496px) 100vw, 496px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p class=wp-block-paragraph&gt;Once you have the Associate under your belt and two or more years of real-world AWS design experience, the &lt;a href=https://aws.amazon.com/certification/certified-solutions-architect-professional/ target=_blank rel=&#34;noreferrer noopener&#34;&gt;AWS Certified Solutions Architect – Professional (SAP-C02)&lt;/a&gt; is the natural and most rewarding next step. This is the certification that truly separates architects from administrators.&lt;p class=wp-block-paragraph&gt;The exam expects you to work across complex, multi-account environments and evaluate architectural trade-offs under real business constraints. It is demanding — but the payoff is clear. The national median base salary for professionals holding SAP-C02 sits at approximately &lt;a href=https://techjacksolutions.com/it-certifications/aws-solutions-architect-professional/ target=_blank rel=&#34;noreferrer noopener&#34;&gt;$175,847&lt;/a&gt;, with senior-level practitioners regularly clearing $220,000+.&lt;p class=wp-block-paragraph&gt;Moreover, as iCert Global notes, the Professional tier is what transforms someone from a &lt;a href=https://www.icertglobal.com/blog/top-cloud-certifications-2026-aws-azure-and-gcp-guide target=_blank rel=&#34;noreferrer noopener&#34;&gt;technician into a strategic partner&lt;/a&gt; — the person who oversees the entire technical lifecycle of an organisation’s cloud infrastructure.&lt;h3 class=wp-block-heading&gt;3. Microsoft Certified: Azure Solutions Architect Expert (AZ-305)&lt;/h3&gt;&lt;div class=wp-block-image&gt;&lt;figure class=&#34;aligncenter size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-33-06.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-33-06.png decoding=async width=502 height=158 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-33-06.png alt class=wp-image-144103 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-33-06.png 502w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-33-06-300x94.png 300w&#34; data-sizes=&#34;(max-width: 502px) 100vw, 502px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=502 height=158 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-33-06.png alt class=wp-image-144103 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-33-06.png 502w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-33-06-300x94.png 300w&#34; sizes=&#34;(max-width: 502px) 100vw, 502px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p class=wp-block-paragraph&gt;Azure holds the second-largest slice of the cloud market — around 21% — and is trusted by &lt;a href=https://kodekloud.com/blog/top-five-cloud-certifications-to-pursue-in-2025/ target=_blank rel=&#34;noreferrer noopener&#34;&gt;over 95% of Fortune 500 companies&lt;/a&gt;. For architects targeting large enterprise environments, banking, healthcare, or government, the &lt;a href=https://learn.microsoft.com/en-us/credentials/certifications/azure-solutions-architect/ target=_blank rel=&#34;noreferrer noopener&#34;&gt;Azure Solutions Architect Expert (AZ-305)&lt;/a&gt; is effectively a mandatory credential.&lt;div style=&#34;display:inline-block; margin: 15px 0;&#34;&gt;&lt;div id=adngin-JavaCodeGeeks_incontent_video-0 style=display:inline-block;&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;p class=wp-block-paragraph&gt;The exam covers four domains: identity and governance (25–30%), data storage solutions (25–30%), business continuity (10–15%), and infrastructure design (30–35%). Importantly, you must hold the &lt;a href=https://learn.microsoft.com/en-us/credentials/certifications/azure-administrator/ target=_blank rel=&#34;noreferrer noopener&#34;&gt;Azure Administrator Associate (AZ-104)&lt;/a&gt; first, which means the full path costs $330 in exam fees. That said, the ROI is exceptional — a $330 investment against a potential $40,000+ salary increase is hard to argue with.&lt;p class=wp-block-paragraph&gt;One feature worth highlighting is the renewal model. Unlike AWS’s three-year re-exam requirement, Microsoft offers free annual renewal via a 30-minute online assessment on Microsoft Learn — a practical advantage for professionals who want to stay current without interrupting project work.&lt;h3 class=wp-block-heading&gt;4. Google Professional Cloud Architect (PCA)&lt;/h3&gt;&lt;div class=wp-block-image&gt;&lt;figure class=&#34;aligncenter size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-33-49.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-33-49.png decoding=async width=498 height=160 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-33-49.png alt class=wp-image-144104 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-33-49.png 498w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-33-49-300x96.png 300w&#34; data-sizes=&#34;(max-width: 498px) 100vw, 498px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=498 height=160 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-33-49.png alt class=wp-image-144104 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-33-49.png 498w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-33-49-300x96.png 300w&#34; sizes=&#34;(max-width: 498px) 100vw, 498px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p class=wp-block-paragraph&gt;GCP may have a smaller job market than AWS, but what it lacks in volume it makes up for in salary. Google’s &lt;a href=https://cloud.google.com/learn/certification/cloud-architect target=_blank rel=&#34;noreferrer noopener&#34;&gt;Professional Cloud Architect&lt;/a&gt; commands average salaries of around $152,550, with top earners crossing $192,000 — &lt;a href=https://certempire.com/gcp-certification-cost/ target=_blank rel=&#34;noreferrer noopener&#34;&gt;the highest average of the big three cloud providers&lt;/a&gt;.&lt;p class=wp-block-paragraph&gt;What makes GCP particularly interesting in 2026 is its positioning around AI, ML, and data analytics. Google’s Kubernetes-native environment and BigQuery ecosystem make it the platform of choice for data-driven startups, research institutions, and organisations with heavy ML workloads. The PCA exam itself uses a unique case-study format — candidates work through four pre-published scenarios including EHR Healthcare, Mountkirk Games, and TerramEarth — which tests real architectural judgment rather than rote recall.&lt;p class=wp-block-paragraph&gt;If your work or target employer leans heavily on data pipelines, Kubernetes, or generative AI infrastructure, GCP PCA deserves a serious look, either as a primary credential or as a complement to an existing AWS certification.&lt;h2 class=wp-block-heading&gt;Quick Comparison: The Big Three Architect Certs&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;Before moving to specialisations, it is worth placing the three flagship credentials side by side so you can quickly gauge which best matches your situation:&lt;figure class=wp-block-table&gt;&lt;table class=has-fixed-layout&gt;&lt;thead&gt;&lt;tr&gt;&lt;th class=has-text-align-left data-align=left&gt;Credential&lt;th class=has-text-align-left data-align=left&gt;Provider&lt;th class=has-text-align-left data-align=left&gt;Exam Cost&lt;th class=has-text-align-left data-align=left&gt;Avg Salary&lt;th class=has-text-align-left data-align=left&gt;Best For&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;SAA-C03&lt;/strong&gt;&lt;td&gt;AWS&lt;td&gt;$150&lt;td&gt;~$136k&lt;td&gt;Entry-level architects, startups&lt;tr&gt;&lt;td&gt;&lt;strong&gt;SAP-C02&lt;/strong&gt;&lt;td&gt;AWS&lt;td&gt;$300&lt;td&gt;~$175k&lt;td&gt;Senior architects, enterprise AWS&lt;tr&gt;&lt;td&gt;&lt;strong&gt;AZ-305&lt;/strong&gt;&lt;td&gt;Azure&lt;td&gt;$165 (+prereq)&lt;td&gt;~$147k&lt;td&gt;Enterprise, Microsoft-shop environments&lt;tr&gt;&lt;td&gt;&lt;strong&gt;GCP PCA&lt;/strong&gt;&lt;td&gt;Google Cloud&lt;td&gt;$200&lt;td&gt;~$152k&lt;td&gt;Data/AI/ML-heavy workloads&lt;/table&gt;&lt;/figure&gt;&lt;h3 class=wp-block-heading&gt;5. AWS Certified Security – Specialty (SCS-C02)&lt;/h3&gt;&lt;div class=wp-block-image&gt;&lt;figure class=&#34;aligncenter size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-34-34.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-34-34.png decoding=async width=493 height=158 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-34-34.png alt class=wp-image-144105 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-34-34.png 493w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-34-34-300x96.png 300w&#34; data-sizes=&#34;(max-width: 493px) 100vw, 493px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=493 height=158 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-34-34.png alt class=wp-image-144105 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-34-34.png 493w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-34-34-300x96.png 300w&#34; sizes=&#34;(max-width: 493px) 100vw, 493px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p class=wp-block-paragraph&gt;Security is no longer a separate concern architects hand off to a different team — it is baked into every design decision. The &lt;a href=https://aws.amazon.com/certification/certified-security-specialty/ target=_blank rel=&#34;noreferrer noopener&#34;&gt;AWS Certified Security – Specialty (SCS-C02)&lt;/a&gt; validates deep expertise in identity and access management, encryption at scale, logging, and compliance frameworks like HIPAA, PCI-DSS 4.0, and FedRAMP.&lt;p class=wp-block-paragraph&gt;In 2026, demand for this credential is being pushed upward by continued AWS migrations and increasingly tight regulatory environments. Senior cloud security architects in major US metros are clustering &lt;a href=https://unihackers.com/certifications/aws-security-specialty target=_blank rel=&#34;noreferrer noopener&#34;&gt;around $180,000&lt;/a&gt;. Many professionals also combine SCS-C02 with Azure AZ-500 to position themselves as multi-cloud security architects — a combination that typically commands a 15–20% salary premium over single-cloud specialists.&lt;blockquote class=&#34;wp-block-quote is-layout-flow wp-block-quote-is-layout-flow&#34;&gt;&lt;p class=wp-block-paragraph&gt;There are no mandatory prerequisites for SCS-C02, but AWS recommends at least two years of hands-on experience specifically securing AWS workloads. The scenario-based exam format is unforgiving if you lack real operational exposure.&lt;/blockquote&gt;&lt;h3 class=wp-block-heading&gt;6. HashiCorp Certified: Terraform Associate (004)&lt;/h3&gt;&lt;div class=wp-block-image&gt;&lt;figure class=&#34;aligncenter size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-35-27.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-35-27.png decoding=async width=498 height=159 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-35-27.png alt class=wp-image-144106 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-35-27.png 498w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-35-27-300x96.png 300w&#34; data-sizes=&#34;(max-width: 498px) 100vw, 498px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=498 height=159 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-35-27.png alt class=wp-image-144106 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-35-27.png 498w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-35-27-300x96.png 300w&#34; sizes=&#34;(max-width: 498px) 100vw, 498px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p class=wp-block-paragraph&gt;At $70.50, the &lt;a href=https://www.hashicorp.com/certifications/terraform-associate target=_blank rel=&#34;noreferrer noopener&#34;&gt;HashiCorp Certified: Terraform Associate&lt;/a&gt; is one of the most affordable serious credentials in the industry — and the combination of AWS Solutions Architect + Terraform Associate is widely considered one of the strongest resume stacks for cloud engineering roles in 2026.&lt;p class=wp-block-paragraph&gt;The numbers back this up: Terraform appears in &lt;a href=https://www.citadelcloudmanagement.com/blogs/news/best-cloud-certifications-2026-12-certs-ranked-by-roi-and-salary-impact target=_blank rel=&#34;noreferrer noopener&#34;&gt;42% of infrastructure engineering job postings on LinkedIn as of Q1 2026&lt;/a&gt; — far ahead of CloudFormation (18%) and Pulumi (7%). The exam covers HCL syntax, state management, modules, workspaces, and Terraform Cloud workflows. Version 004 launched in January 2026 and covers Terraform 1.12.&lt;p class=wp-block-paragraph&gt;Even for architects who are not primarily infrastructure engineers, holding this certification signals that you can own the full IaC story — designing not just the architecture, but the automation that deploys it repeatably and reliably.&lt;h3 class=wp-block-heading&gt;7. Certified Kubernetes Administrator (CKA)&lt;/h3&gt;&lt;div class=wp-block-image&gt;&lt;figure class=&#34;aligncenter size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-36-05.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-36-05.png decoding=async width=501 height=161 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-36-05.png alt class=wp-image-144107 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-36-05.png 501w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-36-05-300x96.png 300w&#34; data-sizes=&#34;(max-width: 501px) 100vw, 501px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=501 height=161 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-36-05.png alt class=wp-image-144107 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-36-05.png 501w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-36-05-300x96.png 300w&#34; sizes=&#34;(max-width: 501px) 100vw, 501px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p class=wp-block-paragraph&gt;Modern cloud architectures are containerised architectures. As a result, the &lt;a href=https://training.linuxfoundation.org/certification/certified-kubernetes-administrator-cka/ target=_blank rel=&#34;noreferrer noopener&#34;&gt;Certified Kubernetes Administrator (CKA)&lt;/a&gt; from the Linux Foundation has become a valuable complement to any cloud architect’s credentials — particularly for those designing microservices platforms or overseeing platform engineering teams.&lt;p class=wp-block-paragraph&gt;The CKA is notably different from multiple-choice exams. It is a two-hour, fully hands-on, performance-based exam where you solve real cluster problems at the command line. This means you either know how Kubernetes works or you don’t — there is no guessing your way through it. Topics include cluster architecture, networking, storage, workloads, security, and troubleshooting.&lt;p class=wp-block-paragraph&gt;The exam includes two attempts, which helps offset the higher cost. Furthermore, Kubernetes expertise pairs exceptionally well with GCP PCA given Google’s Kubernetes-native environment, as well as with Azure AKS and AWS EKS architecture work.&lt;h3 class=wp-block-heading&gt;8. AWS Certified Machine Learning – Specialty (MLS-C01)&lt;/h3&gt;&lt;div class=wp-block-image&gt;&lt;figure class=&#34;aligncenter size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-36-51.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-36-51.png decoding=async width=499 height=159 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-36-51.png alt class=wp-image-144108 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-36-51.png 499w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-36-51-300x96.png 300w&#34; data-sizes=&#34;(max-width: 499px) 100vw, 499px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=499 height=159 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-36-51.png alt class=wp-image-144108 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-36-51.png 499w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-36-51-300x96.png 300w&#34; sizes=&#34;(max-width: 499px) 100vw, 499px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p class=wp-block-paragraph&gt;The AI/ML hiring premium is real and it is growing. The &lt;a href=https://aws.amazon.com/certification/certified-machine-learning-specialty/ target=_blank rel=&#34;noreferrer noopener&#34;&gt;AWS Certified Machine Learning – Specialty (MLS-C01)&lt;/a&gt; delivers an average salary uplift of around $33,000 — among the highest of any AWS certification — and ML-related certifications are growing at 14% year-over-year in 2026.&lt;p class=wp-block-paragraph&gt;As enterprises accelerate deployments of generative AI, computer vision, and NLP systems on AWS, architects who understand how to design ML infrastructure — from data ingestion pipelines through SageMaker training and inference endpoints — are commanding significant premiums. This certification validates exactly that knowledge base.&lt;p class=wp-block-paragraph&gt;It is worth noting that MLS-C01 demands genuine machine learning knowledge, not just cloud mechanics. The study commitment is substantial (180–250 hours assuming foundational ML knowledge), but for architects targeting AI-focused organisations or leadership roles in data-heavy verticals, the investment is clearly justified.&lt;h3 class=wp-block-heading&gt;9. CISSP – Certified Information Systems Security Professional&lt;/h3&gt;&lt;div class=wp-block-image&gt;&lt;figure class=&#34;aligncenter size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-37-28.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-37-28.png decoding=async width=499 height=161 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-37-28.png alt class=wp-image-144109 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-37-28.png 499w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-37-28-300x97.png 300w&#34; data-sizes=&#34;(max-width: 499px) 100vw, 499px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=499 height=161 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-37-28.png alt class=wp-image-144109 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-37-28.png 499w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-20_22-37-28-300x97.png 300w&#34; sizes=&#34;(max-width: 499px) 100vw, 499px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p class=wp-block-paragraph&gt;While every other certification on this list is cloud-provider-specific or tool-focused, the &lt;a href=https://www.isc2.org/certifications/cissp target=_blank rel=&#34;noreferrer noopener&#34;&gt;CISSP&lt;/a&gt; is the globally recognised standard for senior security leadership — and it belongs here because solution architects increasingly operate at the intersection of system design and enterprise security governance.&lt;p class=wp-block-paragraph&gt;CISSP validates expertise across eight domains of security knowledge, including security and risk management, asset security, software development security, and identity and access management. Unlike the AWS Security Specialty (which is tightly scoped to AWS controls), CISSP speaks to boards, regulators, and auditors — making it valuable for architects who are also influencing security strategy at the organisational level.&lt;p class=wp-block-paragraph&gt;The exam is genuinely demanding: the CAT (Computerised Adaptive Testing) format runs between 100 and 150 questions over up to six hours. Moreover, candidates need five years of paid work experience in at least two of the eight domains. This is not an entry-level certification — but for architects targeting CISO adjacency, Principal Architect, or Distinguished Engineer tracks, it is a powerful differentiator.&lt;h2 class=wp-block-heading&gt;Choosing the Right Path for Your Stage&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;With nine certifications on the table, the question naturally becomes: where do you start and in what order? The answer depends largely on your current role, your target employer, and your timeline. As a general framework, however, the following progression works well for most architects:&lt;figure class=wp-block-table&gt;&lt;table class=has-fixed-layout&gt;&lt;thead&gt;&lt;tr&gt;&lt;th class=has-text-align-left data-align=left&gt;Career Stage&lt;th class=has-text-align-left data-align=left&gt;Recommended Certs&lt;th class=has-text-align-left data-align=left&gt;Why&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Early (0–2 yrs)&lt;/strong&gt;&lt;td&gt;AWS SAA-C03 → Terraform Associate&lt;td&gt;Best ROI and job market entry point; IaC shows immediate practical value&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Mid (2–5 yrs)&lt;/strong&gt;&lt;td&gt;AWS SAP-C02 or AZ-305 → CKA&lt;td&gt;Architect-level credentials that open senior roles; Kubernetes for platform work&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Senior (5+ yrs)&lt;/strong&gt;&lt;td&gt;GCP PCA + AWS Security Specialty or MLS-C01&lt;td&gt;Multi-cloud positioning; AI/security specialisation for premium roles&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Leadership track&lt;/strong&gt;&lt;td&gt;CISSP&lt;td&gt;Security governance credibility for Principal/Distinguished/CISO-adjacent roles&lt;/table&gt;&lt;/figure&gt;&lt;blockquote class=&#34;wp-block-quote is-layout-flow wp-block-quote-is-layout-flow&#34;&gt;&lt;p class=wp-block-paragraph&gt;&lt;strong&gt;Multi-cloud note:&lt;/strong&gt; In 2026, architects are increasingly expected to understand AI infrastructure orchestration alongside traditional cloud design. The emerging sweet spot is holding at least two major cloud credentials — typically AWS plus either Azure or GCP — combined with either an IaC or security specialisation. This combination is becoming a baseline expectation at Fortune 500 firms.&lt;/blockquote&gt;&lt;h2 class=wp-block-heading&gt;What We Learned&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;Cloud certifications in 2026 are far more than exam badges — they are role-specific signals of architectural maturity. We walked through nine credentials that matter most for solution architects this year, starting with the high-ROI AWS SAA-C03 and SAP-C02 pair, moving through Azure AZ-305 and GCP PCA for multi-cloud positioning, and extending into the specialisations — Terraform for IaC fluency, CKA for container platforms, AWS Security Specialty and CISSP for security leadership, and AWS MLS-C01 for the AI/ML premium.&lt;p class=wp-block-paragraph&gt;The clearest takeaway is that the most valuable architects in 2026 are not single-cloud generalists — they are multi-cloud designers with a meaningful specialisation in security, IaC, or AI. Choosing your path deliberately, starting with the credential that best matches your current environment and target role, is far more effective than chasing every badge at once.&lt;/p&gt;&lt;style&gt;.lepopup-progress-60 div.lepopup-progress-t1&gt;div{background-color:#e0e0e0;}.lepopup-progress-60 div.lepopup-progress-t1&gt;div&gt;div{background-color:#bd4070;}.lepopup-progress-60 div.lepopup-progress-t1&gt;div&gt;div{color:#ffffff;}.lepopup-progress-60 div.lepopup-progress-t1&gt;label{color:#444444;}.lepopup-form-60, .lepopup-form-60 *, .lepopup-progress-60 {font-size:15px;color:#444444;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-signature-box span i{font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#555555;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-signature-box,.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;text&#39;],.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;email&#39;],.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;password&#39;],.lepopup-form-60 .lepopup-element div.lepopup-input select,.lepopup-form-60 .lepopup-element div.lepopup-input select option,.lepopup-form-60 .lepopup-element div.lepopup-input textarea{font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#555555;font-style:normal;text-decoration:none;text-align:left;background-color:rgba(255, 255, 255, 0.7);background-image:none;border-width:1px;border-style:solid;border-color:#cccccc;border-radius:0px;box-shadow: inset 0px 0px 15px -7px #000000;}.lepopup-form-60 .lepopup-element div.lepopup-input ::placeholder{color:#555555; opacity: 0.9;} .lepopup-form-60 .lepopup-element div.lepopup-input ::-ms-input-placeholder{color:#555555; opacity: 0.9;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect::-webkit-scrollbar-thumb{background-color:#cccccc;}.lepopup-form-60 .lepopup-element div.lepopup-input&gt;i.lepopup-icon-left, .lepopup-form-60 .lepopup-element div.lepopup-input&gt;i.lepopup-icon-right{font-size:20px;color:#444444;border-radius:0px;}.lepopup-form-60 .lepopup-element .lepopup-button,.lepopup-form-60 .lepopup-element .lepopup-button:visited{font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#ffffff;font-weight:700;font-style:normal;text-decoration:none;text-align:center;background-color:#326693;background-image:none;border-width:1px;border-style:solid;border-color:#326693;border-radius:0px;box-shadow:none;}.lepopup-form-60 .lepopup-element div.lepopup-input .lepopup-imageselect+label{border-width:1px;border-style:solid;border-color:#cccccc;border-radius:0px;box-shadow:none;}.lepopup-form-60 .lepopup-element div.lepopup-input .lepopup-imageselect+label span.lepopup-imageselect-label{font-size:15px;color:#444444;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl:checked+label:after{background-color:rgba(255, 255, 255, 0.7);}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-classic+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-fa-check+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-square+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl+label{background-color:rgba(255, 255, 255, 0.7);border-color:#cccccc;color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-square:checked+label:after{background-color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl:checked+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl+label:after{background-color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-classic+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-fa-check+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-dot+label{background-color:rgba(255, 255, 255, 0.7);border-color:#cccccc;color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-dot:checked+label:after{background-color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect&gt;input[type=&#39;checkbox&#39;]+label:hover{background-color:#bd4070;color:#ffffff;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect&gt;input[type=&#39;checkbox&#39;]:checked+label{background-color:#a93a65;color:#ffffff;}.lepopup-form-60 .lepopup-element input[type=&#39;checkbox&#39;].lepopup-tile+label, .lepopup-form-60 .lepopup-element input[type=&#39;radio&#39;].lepopup-tile+label {font-size:15px;color:#444444;font-style:normal;text-decoration:none;text-align:center;background-color:#ffffff;background-image:none;border-width:1px;border-style:solid;border-color:#cccccc;border-radius:0px;box-shadow:none;}.lepopup-form-60 .lepopup-element-error{font-size:15px;color:#ffffff;font-style:normal;text-decoration:none;text-align:left;background-color:#d9534f;background-image:none;}.lepopup-form-60 .lepopup-element-2 {background-color:rgba(226, 236, 250, 1);background-image:none;border-width:1px;border-style:solid;border-color:rgba(216, 216, 216, 1);border-radius:3px;box-shadow: 1px 1px 15px -6px #d7e1eb;}.lepopup-form-60 .lepopup-element-3 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:26px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-3 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:26px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-3 .lepopup-element-html-content {min-height:73px;}.lepopup-form-60 .lepopup-element-4 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:19px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-4 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:19px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-4 .lepopup-element-html-content {min-height:23px;}.lepopup-form-60 .lepopup-element-5 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-5 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-5 .lepopup-element-html-content {min-height:24px;}.lepopup-form-60 .lepopup-element-6 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-6 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-6 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-7 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-7 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-7 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-8 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-8 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-8 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-9 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-9 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-9 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-10 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-10 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-10 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-11 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-11 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-11 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-12 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-12 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-12 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-13 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-13 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-13 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-14 div.lepopup-input .lepopup-icon-left, .lepopup-form-60 .lepopup-element-14 div.lepopup-input .lepopup-icon-right {line-height:36px;}.lepopup-form-60 .lepopup-element-15 div.lepopup-input{height:auto;line-height:1;}.lepopup-form-60 .lepopup-element-16 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:14px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-16 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:14px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-16 .lepopup-element-html-content {min-height:5px;}.lepopup-form-60 .lepopup-element-19 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#333333;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-19 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#333333;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-19 .lepopup-element-html-content {min-height:363px;}.lepopup-form-60 .lepopup-element-0 * {font-size:15px;color:#ffffff;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-0 {font-size:15px;color:#ffffff;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:#5cb85c;background-image:none;border-width:0px;border-style:solid;border-color:#ccc;border-radius:5px;box-shadow: 1px 1px 15px -6px #000000;padding-top:40px;padding-right:40px;padding-bottom:40px;padding-left:40px;}.lepopup-form-60 .lepopup-element-0 .lepopup-element-html-content {min-height:160px;}&lt;/style&gt;&lt;div class=lepopup-inline style=&#34;margin: 0 auto;&#34;&gt;&lt;div class=&#34;lepopup-form lepopup-form-60 lepopup-form-SUgRqsE2dNq6SYXX lepopup-form-icon-inside lepopup-form-position-middle-right&#34; data-session=0 data-id=SUgRqsE2dNq6SYXX data-form-id=60 data-slug=7lQM6oyWL5bTm5lw data-title=&#34;Under the Post Inline&#34; data-page=1 data-xd=off data-width=820 data-height=430 data-position=middle-right data-esc=off data-enter=on data-disable-scrollbar=off style=display:none;width:820px;height:430px; onclick=event.stopPropagation();&gt;&lt;div class=lepopup-form-inner style=width:820px;height:430px;&gt;&lt;div class=&#34;lepopup-element lepopup-element-2 lepopup-element-rectangle&#34; data-type=rectangle data-top=0 data-left=0 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:501;top:0px;left:0px;width:820px;height:430px;&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-3 lepopup-element-html&#34; data-type=html data-top=7 data-left=10 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:502;top:7px;left:10px;width:797px;height:73px;&gt;&lt;div class=lepopup-element-html-content&gt;Do you want to know how to develop your skillset to become a &lt;span style=&#34;color: #CAB43D; text-shadow: 1px 1px #835D5D;&#34;&gt;Java Rockstar?&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-4 lepopup-element-html&#34; data-type=html data-top=83 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:503;top:83px;left:308px;width:473px;height:23px;&gt;&lt;div class=lepopup-element-html-content&gt;Subscribe to our newsletter to start Rocking &lt;span style=&#34;text-decoration: underline;&#34;&gt;right now!&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-5 lepopup-element-html&#34; data-type=html data-top=107 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:504;top:107px;left:308px;width:473px;height:24px;&gt;&lt;div class=lepopup-element-html-content&gt;To get you started we give you our best selling eBooks for &lt;span style=&#34;color:#e01404; text-shadow: 1px 1px #C99924; font-size: 15px;&#34;&gt;FREE!&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-6 lepopup-element-html&#34; data-type=html data-top=136 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:505;top:136px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;1.&lt;/span&gt; JPA Mini Book&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-7 lepopup-element-html&#34; data-type=html data-top=156 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:506;top:156px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;2.&lt;/span&gt; JVM Troubleshooting Guide&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-8 lepopup-element-html&#34; data-type=html data-top=176 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:507;top:176px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;3.&lt;/span&gt; JUnit Tutorial for Unit Testing&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-9 lepopup-element-html&#34; data-type=html data-top=196 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:508;top:196px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;4.&lt;/span&gt; Java Annotations Tutorial&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-10 lepopup-element-html&#34; data-type=html data-top=216 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:509;top:216px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;5.&lt;/span&gt; Java Interview Questions&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-11 lepopup-element-html&#34; data-type=html data-top=236 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:510;top:236px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;6.&lt;/span&gt; Spring Interview Questions&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-12 lepopup-element-html&#34; data-type=html data-top=256 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:511;top:256px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;7.&lt;/span&gt; Android UI Design&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-13 lepopup-element-html&#34; data-type=html data-top=282 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:512;top:282px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;and many more ....&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-14&#34; data-type=email data-deps data-id=14 data-top=305 data-left=308 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:513;top:305px;left:308px;width:473px;height:36px;&gt;&lt;div class=lepopup-input&gt;&lt;input type=email name=lepopup-14 class=lepopup-ta-left placeholder=&#34;Enter your e-mail...&#34; autocomplete=email data-default aria-label=&#34;Email Field&#34; oninput=lepopup_input_changed(this); onfocus=lepopup_input_error_hide(this);&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-15&#34; data-type=checkbox data-deps data-id=15 data-top=344 data-left=308 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:514;top:344px;left:308px;width:160px;&gt;&lt;div class=&#34;lepopup-input lepopup-cr-layout-1 lepopup-cr-layout-left&#34;&gt;&lt;div class=&#34;lepopup-cr-container lepopup-cr-container-medium lepopup-cr-container-left&#34;&gt;&lt;div class=lepopup-cr-box&gt;&lt;input class=&#34;lepopup-checkbox lepopup-checkbox-classic lepopup-checkbox-medium&#34; type=checkbox name=lepopup-15[] id=lepopup-checkbox-gRRTXqbsRnZ9R8uD-14-0 value=on data-default=off onchange=lepopup_input_changed(this);&gt;&lt;label for=lepopup-checkbox-gRRTXqbsRnZ9R8uD-14-0 onclick=lepopup_input_error_hide(this);&gt;&lt;/label&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-cr-label lepopup-ta-left&#34;&gt;&lt;label for=lepopup-checkbox-gRRTXqbsRnZ9R8uD-14-0 onclick=lepopup_input_error_hide(this);&gt;&lt;/label&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-16 lepopup-element-html&#34; data-type=html data-top=344 data-left=338 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:515;top:344px;left:338px;width:350px;height:5px;&gt;&lt;div class=lepopup-element-html-content&gt;I agree to the &lt;a href=https://www.javacodegeeks.com/about/terms-of-use target=_blank&gt;Terms&lt;/a&gt; and &lt;a href=https://www.javacodegeeks.com/about/privacy-policy target=_blank&gt;Privacy Policy&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-17&#34; data-type=button data-top=372 data-left=308 data-animation-in=bounceIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:516;top:372px;left:308px;width:85px;height:37px;&gt;&lt;a class=&#34;lepopup-button lepopup-button-zoom-out&#34; href=https://www.javacodegeeks.com/feed/ onclick=&#34;return lepopup_submit(this);&#34; data-label=&#34;Sign up&#34; data-loading=Loading...&gt;&lt;span&gt;Sign up&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-19 lepopup-element-html&#34; data-type=html data-top=67 data-left=-15 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:518;top:67px;left:-15px;width:320px;height:363px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2015/01/books_promo.png decoding=async data-src=https://www.javacodegeeks.com/wp-content/uploads/2015/01/books_promo.png alt width=320 height=363&gt;&lt;noscript&gt;&lt;img decoding=async src=https://www.javacodegeeks.com/wp-content/uploads/2015/01/books_promo.png alt width=320 height=363&gt;&lt;/noscript&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-form lepopup-form-60 lepopup-form-SUgRqsE2dNq6SYXX lepopup-form-icon-inside lepopup-form-position-middle-right&#34; data-session=0 data-id=SUgRqsE2dNq6SYXX data-form-id=60 data-slug=7lQM6oyWL5bTm5lw data-title=&#34;Under the Post Inline&#34; data-page=confirmation data-xd=off data-width=420 data-height=320 data-position=middle-right data-esc=off data-enter=on data-disable-scrollbar=off style=display:none;width:420px;height:320px; onclick=event.stopPropagation();&gt;&lt;div class=lepopup-form-inner style=width:420px;height:320px;&gt;&lt;div class=&#34;lepopup-element lepopup-element-0 lepopup-element-html&#34; data-type=html data-top=80 data-left=70 data-animation-in=bounceInDown data-animation-out=fadeOutUp style=animation-duration:1000ms;animation-delay:0ms;z-index:500;top:80px;left:70px;width:280px;height:160px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;h4 style=&#34;text-align: center; font-size: 18px; font-weight: bold;&#34;&gt;Thank you!&lt;/h4&gt;&lt;p style=&#34;text-align: center;&#34;&gt;We will contact you soon.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;input type=hidden id=lepopup-logic-SUgRqsE2dNq6SYXX value=[]&gt;&lt;/div&gt;&lt;div class=&#34;post-bottom-meta post-bottom-tags post-tags-classic&#34;&gt;&lt;div class=post-bottom-meta-title&gt;&lt;span class=tie-icon-tags aria-hidden=true&gt;&lt;/span&gt;Tags&lt;/div&gt;&lt;span class=tagcloud&gt;&lt;a href=https://www.javacodegeeks.com/tag/cloud-career rel=tag&gt;Cloud Career&lt;/a&gt; &lt;a href=https://www.javacodegeeks.com/tag/cloud-certifications rel=tag&gt;Cloud Certifications&lt;/a&gt; &lt;a href=https://www.javacodegeeks.com/tag/solution-architecture rel=tag&gt;Solution Architecture&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div id=post-extra-info&gt;&lt;div class=theiaStickySidebar&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=clearfix&gt;&lt;/div&gt;</description>
      <author>Eleftheria Drosopoulou</author>
      <guid>https://www.javacodegeeks.com/2026/06/top-9-role-based-cloud-certifications-for-solution-architects-in-2026.html</guid>
      <pubDate>Wed, 24 Jun 2026 17:21:00 +0000</pubDate>
    </item>
    <item>
      <title>How to Wait for Dynamic Content in Selenium Without Delays</title>
      <link>https://www.javacodegeeks.com/how-to-wait-for-dynamic-content-in-selenium-without-delays.html</link>
      <description>&lt;header class=entry-header-outer&gt;&lt;nav id=breadcrumb&gt;&lt;a href=https://www.javacodegeeks.com/&gt;&lt;span class=tie-icon-home aria-hidden=true&gt;&lt;/span&gt;Home&lt;/a&gt;&lt;em class=delimiter&gt;»&lt;/em&gt;&lt;a href=https://www.javacodegeeks.com/category/web-development&gt;Web Development&lt;/a&gt;&lt;em class=delimiter&gt;»&lt;/em&gt;&lt;a href=https://www.javacodegeeks.com/category/web-development/javascript&gt;JavaScript&lt;/a&gt;&lt;em class=delimiter&gt;»&lt;/em&gt;&lt;span class=current&gt;How to Wait for Dynamic Content in Selenium Without Delays&lt;/span&gt;&lt;/nav&gt;&lt;div class=entry-header&gt;&lt;span class=post-cat-wrap&gt;&lt;a class=&#34;post-cat tie-cat-1879&#34; href=https://www.javacodegeeks.com/category/web-development/javascript&gt;JavaScript&lt;/a&gt;&lt;/span&gt;&lt;h1 class=&#34;post-title entry-title&#34;&gt;How to Wait for Dynamic Content in Selenium Without Delays&lt;/h1&gt;&lt;/div&gt;&lt;/header&gt;&lt;div class=&#34;entry-content entry clearfix&#34;&gt;&lt;div class=&#34;stream-item stream-item-above-post-content&#34;&gt;&lt;div class=stream-item-size&gt;&lt;div id=adngin-in-post-0 style=&#34;float:left; margin-right:20px; margin-bottom:10px; width:300px; height:274px;&#34;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p class=wp-block-paragraph&gt;Modern web applications are no longer simple HTML pages served from a server and rendered once in the browser. Instead, they are dynamic, JavaScript-driven systems where most of the UI is built or modified after the initial page load. Frameworks like React, Angular, and Vue frequently render content asynchronously, fetch data through API calls, and continuously update the DOM based on user interaction or background processes.&lt;p class=wp-block-paragraph&gt;This shift creates a major challenge for automated testing with Selenium WebDriver: &lt;strong&gt;how do you reliably know when a page is actually ready?&lt;/strong&gt;&lt;p class=wp-block-paragraph&gt;A page may return a &lt;strong&gt;complete&lt;/strong&gt; load event while still rendering critical UI components. Elements may exist in the DOM but not yet be visible or interactive. Data may still be loading in the background. As a result, traditional approaches to waiting for page loads are often insufficient.&lt;p class=wp-block-paragraph&gt;In this article, we’ll explore how to correctly wait for JavaScript-heavy pages in Selenium without relying on arbitrary delays like &lt;code&gt;Thread.sleep()&lt;/code&gt;, and instead build reliable and stable synchronization strategies.&lt;h2 class=wp-block-heading&gt;1. Why Waiting is Hard in JavaScript-Heavy Applications&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;In traditional server-rendered applications, page load behavior was relatively predictable:&lt;ol class=wp-block-list&gt;&lt;li&gt;The browser requests a page&lt;li&gt;Server responds with fully rendered HTML&lt;li&gt;Page finishes loading&lt;li&gt;Test proceeds&lt;/ol&gt;&lt;p class=wp-block-paragraph&gt;But modern applications behave differently:&lt;ul class=wp-block-list&gt;&lt;li&gt;Initial HTML is often minimal (a “shell”)&lt;li&gt;JavaScript loads and renders content dynamically&lt;li&gt;Data is fetched asynchronously via APIs&lt;li&gt;DOM updates occur multiple times after initial load&lt;li&gt;UI components may load at different speeds&lt;/ul&gt;&lt;p class=wp-block-paragraph&gt;This means that even if Selenium detects that the page has &lt;strong&gt;loaded&lt;/strong&gt;, the application may still be:&lt;ul class=wp-block-list&gt;&lt;li&gt;Fetching data from APIs&lt;li&gt;Rendering components&lt;li&gt;Hydrating client-side frameworks&lt;li&gt;Updating the DOM dynamically&lt;/ul&gt;&lt;p class=wp-block-paragraph&gt;So the real challenge is not detecting page load but detecting application readiness.&lt;p class=wp-block-paragraph&gt;&lt;strong&gt;The Problem With Arbitrary Waits&lt;/strong&gt;&lt;p class=wp-block-paragraph&gt;A common beginner approach is using &lt;code&gt;Thread.sleep(5000)&lt;/code&gt;, but while it may seem effective at first, it introduces several problems:&lt;ul class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;Wasted Test Time&lt;/strong&gt;: If the page loads in 1 second, the test still waits 5 seconds unnecessarily, increasing overall execution time significantly when repeated across many tests.&lt;li&gt;&lt;strong&gt;Flaky Tests&lt;/strong&gt;: If the page takes longer than expected due to slow network, server latency, CI/CD load, or API delays, the test may fail even when the application is functioning correctly.&lt;li&gt;&lt;strong&gt;Non-deterministic Behaviour&lt;/strong&gt;: Fixed delays do not adapt to real runtime conditions, making test execution inconsistent and reducing the overall reliability of the test suite.&lt;/ul&gt;&lt;h2 class=wp-block-heading&gt;2. Understanding Selenium Wait Strategies&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;Selenium provides two main synchronization mechanisms:&lt;p class=wp-block-paragraph&gt;&lt;strong&gt;Implicit Wait&lt;/strong&gt;&lt;pre class=brush:javascript&gt;driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));&#xA;&lt;/pre&gt;&lt;p class=wp-block-paragraph&gt;This tells WebDriver to poll the DOM for a certain amount of time when trying to find elements. Limitations include the fact that it only applies to element lookup, does not guarantee full page readiness, and can slow down test execution when used excessively.&lt;p class=wp-block-paragraph&gt;&lt;strong&gt;Explicit Wait (Recommended Approach)&lt;/strong&gt;&lt;p class=wp-block-paragraph&gt;Explicit waits are the main way to reliably synchronize tests in Selenium.&lt;pre class=brush:javascript&gt;WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));&#xA;&lt;/pre&gt;&lt;p class=wp-block-paragraph&gt;We define &lt;strong&gt;exact conditions&lt;/strong&gt; that must be met before proceeding.&lt;div style=&#34;display:inline-block; margin: 15px 0;&#34;&gt;&lt;div id=adngin-JavaCodeGeeks_incontent_video-0 style=display:inline-block;&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;pre class=brush:javascript&gt;wait.until(ExpectedConditions.visibilityOfElementLocated(By.id(&amp;#34;submit&amp;#34;)));&#xA;&lt;/pre&gt;&lt;p class=wp-block-paragraph&gt;This is far more reliable than waiting for a fixed time.&lt;h2 class=wp-block-heading&gt;3. Waiting for Document Ready State&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;One common way to detect page load completion is by checking the browser’s document readiness.&lt;pre class=brush:javascript&gt;public class SeleniumWaitDemo {&#xA;&#xA;    public static void main(String[] args) {&#xA;        WebDriverManager.chromedriver().setup();&#xA;        WebDriver driver = new ChromeDriver();&#xA;&#xA;        driver.get(&amp;#34;https://demoqa.com&amp;#34;);&#xA;&#xA;        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));&#xA;        JavascriptExecutor js = (JavascriptExecutor) driver;&#xA;&#xA;        wait.until(d&#xA;                -&amp;gt; js.executeScript(&amp;#34;return document.readyState&amp;#34;).equals(&amp;#34;complete&amp;#34;)&#xA;        );&#xA;&#xA;        driver.quit();&#xA;    }&#xA;}&#xA;&lt;/pre&gt;&lt;p class=wp-block-paragraph&gt;The document ready state helps you understand how far the browser has gone in loading a page. When the state is &lt;strong&gt;“loading”&lt;/strong&gt;, the page is still in the process of loading. When it becomes &lt;strong&gt;“interactive”&lt;/strong&gt;, the DOM is ready and can be accessed, but some resources like images or scripts may still be loading. Finally, when the state reaches &lt;strong&gt;“complete”&lt;/strong&gt;, it means the page and its resources have finished loading from the browser’s perspective.&lt;p class=wp-block-paragraph&gt;However, this approach has important limitations, especially with modern web applications. Even after the state is &lt;strong&gt;“complete”&lt;/strong&gt;, frameworks like React or Vue may still be rendering components, API calls may still be in progress, and parts of the UI may continue updating dynamically. Because of this, the document ready state should be treated as a starting point or baseline check, rather than a final confirmation that the page is fully ready for interaction.&lt;h2 class=wp-block-heading&gt;4. Waiting for AJAX Requests (jQuery)&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;Many pages load content via AJAX. Selenium cannot directly see network activity, but we can approximate it.&lt;pre class=brush:javascript&gt;public class AjaxWaitExample {&#xA;    &#xA;    public static void main(String[] args) {&#xA;        WebDriverManager.chromedriver().setup();&#xA;        WebDriver driver = new ChromeDriver();&#xA;&#xA;        driver.get(&amp;#34;https://demoqa.com&amp;#34;);&#xA;&#xA;        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(15));&#xA;&#xA;        wait.until(d -&amp;gt; {&#xA;            JavascriptExecutor js = (JavascriptExecutor) d;&#xA;            return (Boolean) js.executeScript(&amp;#34;return jQuery.active === 0&amp;#34;);&#xA;        });&#xA;&#xA;        driver.quit();&#xA;    }&#xA;}&#xA;&#xA;&lt;/pre&gt;&lt;p class=wp-block-paragraph&gt;This code checks the number of active AJAX requests using &lt;code&gt;jQuery.active&lt;/code&gt;. When the value becomes &lt;strong&gt;0&lt;/strong&gt;, it means all AJAX calls have finished. Selenium then waits until this condition is met before continuing. This ensures the page has completed background data loading. However, it only works if the application uses jQuery for AJAX requests.&lt;h2 class=wp-block-heading&gt;5. Wait for JavaScript Framework Stability&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;Modern frameworks often introduce delayed rendering. You may need to wait for framework-specific signals.&lt;p class=wp-block-paragraph&gt;&lt;strong&gt;React applications&lt;/strong&gt;&lt;p class=wp-block-paragraph&gt;You can wait for a root element:&lt;pre class=brush:javascript&gt;wait.until(driver -&amp;gt;&#xA;    driver.findElements(By.cssSelector(&amp;#34;#root&amp;#34;)).size() &amp;gt; 0&#xA;);&#xA;&lt;/pre&gt;&lt;p class=wp-block-paragraph&gt;Then wait for content:&lt;pre class=brush:javascript&gt;wait.until(ExpectedConditions.visibilityOfElementLocated(&#xA;    By.cssSelector(&amp;#34;.app-loaded&amp;#34;)&#xA;));&#xA;&lt;/pre&gt;&lt;p class=wp-block-paragraph&gt;This check ensures that the main React root element has been mounted in the DOM. In React applications, the UI is often rendered inside a single root container, so verifying its presence confirms that the initial rendering phase has started.&lt;p class=wp-block-paragraph&gt;However, this does not guarantee that all components or data inside the application have fully loaded. It only indicates that the React application has been initialized and attached to the DOM, making it a useful early-stage synchronization point.&lt;p class=wp-block-paragraph&gt;&lt;strong&gt;Angular Applications&lt;/strong&gt;&lt;pre class=brush:javascript&gt;wait.until(driver -&amp;gt;&#xA;    ((JavascriptExecutor) driver).executeScript(&#xA;        &amp;#34;return window.getAllAngularTestabilities()[0].isStable()&amp;#34;&#xA;    ).equals(true)&#xA;);&#xA;&lt;/pre&gt;&lt;p class=wp-block-paragraph&gt;This approach checks Angular’s internal &lt;a href=https://angular.dev/api/core/Testability target=_blank rel=&#34;noreferrer noopener&#34;&gt;testability API&lt;/a&gt; to determine whether the application is stable. When &lt;code&gt;isStable()&lt;/code&gt; returns &lt;code&gt;true&lt;/code&gt;, it means Angular has finished processing all asynchronous tasks such as HTTP requests, timers, and change detection cycles.&lt;p class=wp-block-paragraph&gt;This makes it a more reliable signal compared to generic DOM checks, as it reflects the actual internal state of the Angular framework. However, it only works in environments where Angular testability is enabled and properly exposed.&lt;h2 class=wp-block-heading&gt;6. Wait for Visibility + Interactivity&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;In many cases, an element may already exist in the DOM but still not be ready for user interaction. It might be hidden, disabled, or still being rendered by JavaScript. Because of this, simply checking that an element is present is not enough. You need to ensure that the element is both visible and ready to be interacted with before performing actions like clicks or typing.&lt;pre class=brush:javascript&gt;WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));&#xA;&#xA;WebElement button = wait.until(&#xA;    ExpectedConditions.elementToBeClickable(By.id(&amp;#34;submit&amp;#34;))&#xA;);&#xA;&#xA;button.click();&#xA;&lt;/pre&gt;&lt;p class=wp-block-paragraph&gt;This code waits until the target element is not only present in the DOM but also visible and enabled, meaning it can be safely interacted with. Once Selenium confirms that the element is clickable, it returns the WebElement and allows the action to proceed.&lt;p class=wp-block-paragraph&gt;This helps prevent common issues such as &lt;code&gt;ElementNotInteractableException&lt;/code&gt; or click actions being ignored because the element was still loading or covered by another UI layer.&lt;h2 class=wp-block-heading&gt;7. Combining Multiple Wait Conditions&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;In real-world applications, a single wait condition is often not enough to confirm that a page is fully ready. Modern web apps load in multiple stages, including initial rendering, API calls, and dynamic UI updates. Because of this, a reliable approach is to combine multiple wait strategies to ensure the application is truly stable before interacting with it.&lt;pre class=brush:javascript&gt;WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(20));&#xA;&#xA;JavascriptExecutor js = (JavascriptExecutor) driver;&#xA;&#xA;// 1. Wait for document ready&#xA;wait.until(d -&amp;gt; js.executeScript(&amp;#34;return document.readyState&amp;#34;).equals(&amp;#34;complete&amp;#34;));&#xA;&#xA;// 2. Wait for main container&#xA;wait.until(ExpectedConditions.visibilityOfElementLocated(By.id(&amp;#34;app&amp;#34;)));&#xA;&#xA;// 3. Wait for final UI element&#xA;wait.until(ExpectedConditions.elementToBeClickable(By.id(&amp;#34;dashboard-link&amp;#34;)));&#xA;&lt;/pre&gt;&lt;p class=wp-block-paragraph&gt;This approach ensures that different layers of the application are validated step by step. First, it confirms that the browser has completed the initial page load. Then it checks that the main application container is visible, indicating that the UI has been rendered.&lt;p class=wp-block-paragraph&gt;Finally, it waits for a specific interactive element to become clickable, ensuring the page is fully ready for user actions. By combining these conditions, tests become significantly more stable and less prone to timing issues.&lt;h2 class=wp-block-heading&gt;8. Conclusion&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;In this article, we explored how to handle waiting for complex JavaScript-driven pages in &lt;a href=https://www.javacodegeeks.com/2021/07/why-selenium-webdriver-should-be-your-first-choice-for-automation-testing.html target=_blank rel=&#34;noreferrer noopener&#34;&gt;Selenium WebDriver&lt;/a&gt; using Java. We looked at why traditional approaches like &lt;code&gt;Thread.sleep()&lt;/code&gt; are unreliable and how modern web applications require more intelligent synchronization strategies.&lt;p class=wp-block-paragraph&gt;We also examined several practical techniques, including explicit waits, document ready state checks, framework-specific stability checks for React and Angular, AJAX completion handling, and visibility-based element waits. Each approach helps address different layers of modern web application behaviour. Ultimately, the key takeaway is that effective Selenium automation is not about waiting for time, but waiting for conditions.&lt;h2 class=wp-block-heading&gt;9. Download the Source Code&lt;/h2&gt;&lt;div class=download&gt;&lt;strong&gt;Download&lt;/strong&gt;&lt;br&gt;You can download the full source code of this example here: &lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/selenium-wait-demo.zip&gt;&lt;strong&gt;Java Selenium wait for complex JavaScript&lt;/strong&gt;&lt;/a&gt;&lt;/div&gt;&lt;p class=wp-block-paragraph&gt;This article explored how to manage wait strategies in Java Selenium for complex, JavaScript-driven pages.&lt;/p&gt;&lt;style&gt;.lepopup-progress-60 div.lepopup-progress-t1&gt;div{background-color:#e0e0e0;}.lepopup-progress-60 div.lepopup-progress-t1&gt;div&gt;div{background-color:#bd4070;}.lepopup-progress-60 div.lepopup-progress-t1&gt;div&gt;div{color:#ffffff;}.lepopup-progress-60 div.lepopup-progress-t1&gt;label{color:#444444;}.lepopup-form-60, .lepopup-form-60 *, .lepopup-progress-60 {font-size:15px;color:#444444;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-signature-box span i{font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#555555;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-signature-box,.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;text&#39;],.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;email&#39;],.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;password&#39;],.lepopup-form-60 .lepopup-element div.lepopup-input select,.lepopup-form-60 .lepopup-element div.lepopup-input select option,.lepopup-form-60 .lepopup-element div.lepopup-input textarea{font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#555555;font-style:normal;text-decoration:none;text-align:left;background-color:rgba(255, 255, 255, 0.7);background-image:none;border-width:1px;border-style:solid;border-color:#cccccc;border-radius:0px;box-shadow: inset 0px 0px 15px -7px #000000;}.lepopup-form-60 .lepopup-element div.lepopup-input ::placeholder{color:#555555; opacity: 0.9;} .lepopup-form-60 .lepopup-element div.lepopup-input ::-ms-input-placeholder{color:#555555; opacity: 0.9;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect::-webkit-scrollbar-thumb{background-color:#cccccc;}.lepopup-form-60 .lepopup-element div.lepopup-input&gt;i.lepopup-icon-left, .lepopup-form-60 .lepopup-element div.lepopup-input&gt;i.lepopup-icon-right{font-size:20px;color:#444444;border-radius:0px;}.lepopup-form-60 .lepopup-element .lepopup-button,.lepopup-form-60 .lepopup-element .lepopup-button:visited{font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#ffffff;font-weight:700;font-style:normal;text-decoration:none;text-align:center;background-color:#326693;background-image:none;border-width:1px;border-style:solid;border-color:#326693;border-radius:0px;box-shadow:none;}.lepopup-form-60 .lepopup-element div.lepopup-input .lepopup-imageselect+label{border-width:1px;border-style:solid;border-color:#cccccc;border-radius:0px;box-shadow:none;}.lepopup-form-60 .lepopup-element div.lepopup-input .lepopup-imageselect+label span.lepopup-imageselect-label{font-size:15px;color:#444444;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl:checked+label:after{background-color:rgba(255, 255, 255, 0.7);}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-classic+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-fa-check+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-square+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl+label{background-color:rgba(255, 255, 255, 0.7);border-color:#cccccc;color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-square:checked+label:after{background-color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl:checked+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl+label:after{background-color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-classic+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-fa-check+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-dot+label{background-color:rgba(255, 255, 255, 0.7);border-color:#cccccc;color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-dot:checked+label:after{background-color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect&gt;input[type=&#39;checkbox&#39;]+label:hover{background-color:#bd4070;color:#ffffff;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect&gt;input[type=&#39;checkbox&#39;]:checked+label{background-color:#a93a65;color:#ffffff;}.lepopup-form-60 .lepopup-element input[type=&#39;checkbox&#39;].lepopup-tile+label, .lepopup-form-60 .lepopup-element input[type=&#39;radio&#39;].lepopup-tile+label {font-size:15px;color:#444444;font-style:normal;text-decoration:none;text-align:center;background-color:#ffffff;background-image:none;border-width:1px;border-style:solid;border-color:#cccccc;border-radius:0px;box-shadow:none;}.lepopup-form-60 .lepopup-element-error{font-size:15px;color:#ffffff;font-style:normal;text-decoration:none;text-align:left;background-color:#d9534f;background-image:none;}.lepopup-form-60 .lepopup-element-2 {background-color:rgba(226, 236, 250, 1);background-image:none;border-width:1px;border-style:solid;border-color:rgba(216, 216, 216, 1);border-radius:3px;box-shadow: 1px 1px 15px -6px #d7e1eb;}.lepopup-form-60 .lepopup-element-3 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:26px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-3 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:26px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-3 .lepopup-element-html-content {min-height:73px;}.lepopup-form-60 .lepopup-element-4 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:19px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-4 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:19px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-4 .lepopup-element-html-content {min-height:23px;}.lepopup-form-60 .lepopup-element-5 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-5 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-5 .lepopup-element-html-content {min-height:24px;}.lepopup-form-60 .lepopup-element-6 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-6 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-6 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-7 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-7 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-7 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-8 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-8 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-8 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-9 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-9 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-9 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-10 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-10 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-10 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-11 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-11 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-11 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-12 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-12 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-12 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-13 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-13 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-13 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-14 div.lepopup-input .lepopup-icon-left, .lepopup-form-60 .lepopup-element-14 div.lepopup-input .lepopup-icon-right {line-height:36px;}.lepopup-form-60 .lepopup-element-15 div.lepopup-input{height:auto;line-height:1;}.lepopup-form-60 .lepopup-element-16 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:14px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-16 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:14px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-16 .lepopup-element-html-content {min-height:5px;}.lepopup-form-60 .lepopup-element-19 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#333333;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-19 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#333333;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-19 .lepopup-element-html-content {min-height:363px;}.lepopup-form-60 .lepopup-element-0 * {font-size:15px;color:#ffffff;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-0 {font-size:15px;color:#ffffff;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:#5cb85c;background-image:none;border-width:0px;border-style:solid;border-color:#ccc;border-radius:5px;box-shadow: 1px 1px 15px -6px #000000;padding-top:40px;padding-right:40px;padding-bottom:40px;padding-left:40px;}.lepopup-form-60 .lepopup-element-0 .lepopup-element-html-content {min-height:160px;}&lt;/style&gt;&lt;div class=lepopup-inline style=&#34;margin: 0 auto;&#34;&gt;&lt;div class=&#34;lepopup-form lepopup-form-60 lepopup-form-64IGQ8TLHEqO2MSF lepopup-form-icon-inside lepopup-form-position-middle-right&#34; data-session=0 data-id=64IGQ8TLHEqO2MSF data-form-id=60 data-slug=7lQM6oyWL5bTm5lw data-title=&#34;Under the Post Inline&#34; data-page=1 data-xd=off data-width=820 data-height=430 data-position=middle-right data-esc=off data-enter=on data-disable-scrollbar=off style=display:none;width:820px;height:430px; onclick=event.stopPropagation();&gt;&lt;div class=lepopup-form-inner style=width:820px;height:430px;&gt;&lt;div class=&#34;lepopup-element lepopup-element-2 lepopup-element-rectangle&#34; data-type=rectangle data-top=0 data-left=0 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:501;top:0px;left:0px;width:820px;height:430px;&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-3 lepopup-element-html&#34; data-type=html data-top=7 data-left=10 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:502;top:7px;left:10px;width:797px;height:73px;&gt;&lt;div class=lepopup-element-html-content&gt;Do you want to know how to develop your skillset to become a &lt;span style=&#34;color: #CAB43D; text-shadow: 1px 1px #835D5D;&#34;&gt;Java Rockstar?&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-4 lepopup-element-html&#34; data-type=html data-top=83 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:503;top:83px;left:308px;width:473px;height:23px;&gt;&lt;div class=lepopup-element-html-content&gt;Subscribe to our newsletter to start Rocking &lt;span style=&#34;text-decoration: underline;&#34;&gt;right now!&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-5 lepopup-element-html&#34; data-type=html data-top=107 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:504;top:107px;left:308px;width:473px;height:24px;&gt;&lt;div class=lepopup-element-html-content&gt;To get you started we give you our best selling eBooks for &lt;span style=&#34;color:#e01404; text-shadow: 1px 1px #C99924; font-size: 15px;&#34;&gt;FREE!&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-6 lepopup-element-html&#34; data-type=html data-top=136 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:505;top:136px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;1.&lt;/span&gt; JPA Mini Book&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-7 lepopup-element-html&#34; data-type=html data-top=156 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:506;top:156px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;2.&lt;/span&gt; JVM Troubleshooting Guide&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-8 lepopup-element-html&#34; data-type=html data-top=176 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:507;top:176px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;3.&lt;/span&gt; JUnit Tutorial for Unit Testing&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-9 lepopup-element-html&#34; data-type=html data-top=196 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:508;top:196px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;4.&lt;/span&gt; Java Annotations Tutorial&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-10 lepopup-element-html&#34; data-type=html data-top=216 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:509;top:216px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;5.&lt;/span&gt; Java Interview Questions&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-11 lepopup-element-html&#34; data-type=html data-top=236 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:510;top:236px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;6.&lt;/span&gt; Spring Interview Questions&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-12 lepopup-element-html&#34; data-type=html data-top=256 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:511;top:256px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;7.&lt;/span&gt; Android UI Design&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-13 lepopup-element-html&#34; data-type=html data-top=282 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:512;top:282px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;and many more ....&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-14&#34; data-type=email data-deps data-id=14 data-top=305 data-left=308 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:513;top:305px;left:308px;width:473px;height:36px;&gt;&lt;div class=lepopup-input&gt;&lt;input type=email name=lepopup-14 class=lepopup-ta-left placeholder=&#34;Enter your e-mail...&#34; autocomplete=email data-default aria-label=&#34;Email Field&#34; oninput=lepopup_input_changed(this); onfocus=lepopup_input_error_hide(this);&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-15&#34; data-type=checkbox data-deps data-id=15 data-top=344 data-left=308 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:514;top:344px;left:308px;width:160px;&gt;&lt;div class=&#34;lepopup-input lepopup-cr-layout-1 lepopup-cr-layout-left&#34;&gt;&lt;div class=&#34;lepopup-cr-container lepopup-cr-container-medium lepopup-cr-container-left&#34;&gt;&lt;div class=lepopup-cr-box&gt;&lt;input class=&#34;lepopup-checkbox lepopup-checkbox-classic lepopup-checkbox-medium&#34; type=checkbox name=lepopup-15[] id=lepopup-checkbox-cI5VZFgNOidCN8WD-14-0 value=on data-default=off onchange=lepopup_input_changed(this);&gt;&lt;label for=lepopup-checkbox-cI5VZFgNOidCN8WD-14-0 onclick=lepopup_input_error_hide(this);&gt;&lt;/label&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-cr-label lepopup-ta-left&#34;&gt;&lt;label for=lepopup-checkbox-cI5VZFgNOidCN8WD-14-0 onclick=lepopup_input_error_hide(this);&gt;&lt;/label&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-16 lepopup-element-html&#34; data-type=html data-top=344 data-left=338 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:515;top:344px;left:338px;width:350px;height:5px;&gt;&lt;div class=lepopup-element-html-content&gt;I agree to the &lt;a href=https://www.javacodegeeks.com/about/terms-of-use target=_blank&gt;Terms&lt;/a&gt; and &lt;a href=https://www.javacodegeeks.com/about/privacy-policy target=_blank&gt;Privacy Policy&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-17&#34; data-type=button data-top=372 data-left=308 data-animation-in=bounceIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:516;top:372px;left:308px;width:85px;height:37px;&gt;&lt;a class=&#34;lepopup-button lepopup-button-zoom-out&#34; href=https://www.javacodegeeks.com/feed/ onclick=&#34;return lepopup_submit(this);&#34; data-label=&#34;Sign up&#34; data-loading=Loading...&gt;&lt;span&gt;Sign up&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-19 lepopup-element-html&#34; data-type=html data-top=67 data-left=-15 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:518;top:67px;left:-15px;width:320px;height:363px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2015/01/books_promo.png fetchpriority=high decoding=async data-src=https://www.javacodegeeks.com/wp-content/uploads/2015/01/books_promo.png alt width=320 height=363&gt;&lt;noscript&gt;&lt;img fetchpriority=high decoding=async src=https://www.javacodegeeks.com/wp-content/uploads/2015/01/books_promo.png alt width=320 height=363&gt;&lt;/noscript&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-form lepopup-form-60 lepopup-form-64IGQ8TLHEqO2MSF lepopup-form-icon-inside lepopup-form-position-middle-right&#34; data-session=0 data-id=64IGQ8TLHEqO2MSF data-form-id=60 data-slug=7lQM6oyWL5bTm5lw data-title=&#34;Under the Post Inline&#34; data-page=confirmation data-xd=off data-width=420 data-height=320 data-position=middle-right data-esc=off data-enter=on data-disable-scrollbar=off style=display:none;width:420px;height:320px; onclick=event.stopPropagation();&gt;&lt;div class=lepopup-form-inner style=width:420px;height:320px;&gt;&lt;div class=&#34;lepopup-element lepopup-element-0 lepopup-element-html&#34; data-type=html data-top=80 data-left=70 data-animation-in=bounceInDown data-animation-out=fadeOutUp style=animation-duration:1000ms;animation-delay:0ms;z-index:500;top:80px;left:70px;width:280px;height:160px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;h4 style=&#34;text-align: center; font-size: 18px; font-weight: bold;&#34;&gt;Thank you!&lt;/h4&gt;&lt;p style=&#34;text-align: center;&#34;&gt;We will contact you soon.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;input type=hidden id=lepopup-logic-64IGQ8TLHEqO2MSF value=[]&gt;&lt;/div&gt;&lt;div class=&#34;post-bottom-meta post-bottom-tags post-tags-classic&#34;&gt;&lt;div class=post-bottom-meta-title&gt;&lt;span class=tie-icon-tags aria-hidden=true&gt;&lt;/span&gt;Tags&lt;/div&gt;&lt;span class=tagcloud&gt;&lt;a href=https://www.javacodegeeks.com/tag/ajax rel=tag&gt;Ajax&lt;/a&gt; &lt;a href=https://www.javacodegeeks.com/tag/javascript rel=tag&gt;JavaScript&lt;/a&gt; &lt;a href=https://www.javacodegeeks.com/tag/selenium rel=tag&gt;Selenium&lt;/a&gt; &lt;a href=https://www.javacodegeeks.com/tag/selenium-webdriver rel=tag&gt;Selenium WebDriver&lt;/a&gt; &lt;a href=https://www.javacodegeeks.com/tag/software-testing rel=tag&gt;Software Testing&lt;/a&gt; &lt;a href=https://www.javacodegeeks.com/tag/test-automation rel=tag&gt;Test Automation&lt;/a&gt; &lt;a href=https://www.javacodegeeks.com/tag/ui-testing rel=tag&gt;UI Testing&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div id=post-extra-info&gt;&lt;div class=theiaStickySidebar&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=clearfix&gt;&lt;/div&gt;</description>
      <author>Omozegie Aziegbe</author>
      <guid>https://www.javacodegeeks.com/how-to-wait-for-dynamic-content-in-selenium-without-delays.html</guid>
      <pubDate>Wed, 24 Jun 2026 14:15:00 +0000</pubDate>
    </item>
    <item>
      <title>[FREE EBOOKS] How to Do More with Less, 90 Days to Level Up Your Leadership &amp; Four More Best Selling Titles</title>
      <link>https://www.javacodegeeks.com/2026/06/free-ebooks-how-to-do-more-with-less-90-days-to-level-up-your-leadership-four-more-best-selling-titles-2.html</link>
      <description>&lt;header class=entry-header-outer&gt;&lt;nav id=breadcrumb&gt;&lt;a href=https://www.javacodegeeks.com/&gt;&lt;span class=tie-icon-home aria-hidden=true&gt;&lt;/span&gt;Home&lt;/a&gt;&lt;em class=delimiter&gt;»&lt;/em&gt;&lt;a href=https://www.javacodegeeks.com/category/meta-jcg&gt;Meta JCG&lt;/a&gt;&lt;em class=delimiter&gt;»&lt;/em&gt;&lt;span class=current&gt;[FREE EBOOKS] How to Do More with Less, 90 Days to Level Up Your Leadership &amp;amp; Four More Best Selling Titles&lt;/span&gt;&lt;/nav&gt;&lt;div class=entry-header&gt;&lt;span class=post-cat-wrap&gt;&lt;a class=&#34;post-cat tie-cat-16&#34; href=https://www.javacodegeeks.com/category/meta-jcg&gt;Meta JCG&lt;/a&gt;&lt;/span&gt;&lt;h1 class=&#34;post-title entry-title&#34;&gt;[FREE EBOOKS] How to Do More with Less, 90 Days to Level Up Your Leadership &amp;amp; Four More Best Selling Titles&lt;/h1&gt;&lt;/div&gt;&lt;/header&gt;&lt;div class=&#34;entry-content entry clearfix&#34;&gt;&lt;p&gt;Hello fellow geeks,&lt;p&gt;Fresh offers await you on our &lt;a href=https://javacodegeeks.tradepub.com/ target=_blank&gt;Information Technology Research Library&lt;/a&gt;, please have a look!&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width=25% style=&#34;border: 0px;vertical-align: top&#34;&gt;&lt;a href=&#34;https://javacodegeeks.tradepub.com/c/pubRD.mpl?secure=1&amp;amp;sr=oc&amp;amp;_t=oc:&amp;amp;qf=w_wile891&amp;amp;ch=w_wile891-j&#34; target=_blank&gt;&lt;img data-lazyloaded=1 src=https://img.tradepub.com/free/w_wile891/images/w_wile891c4.gif decoding=async data-src=https://img.tradepub.com/free/w_wile891/images/w_wile891c4.gif&gt;&lt;noscript&gt;&lt;img decoding=async src=https://img.tradepub.com/free/w_wile891/images/w_wile891c4.gif&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;td style=&#34;vertical-align: top;border: 0px&#34;&gt;&lt;h2 style=&#34;text-align: center;background: #c8dbf7&#34;&gt;How to Do More with Less: Future-Proofing Yourself in an AI-driven Economy ($28.00 Value) FREE for a Limited Time&lt;/h2&gt;&lt;p&gt;An honest and practical strategy guide to working in a world transformed by AI. In today’s workplace, headlines about artificial intelligence can feel overwhelming. With headlines swinging between promises of utopia and warnings of mass unemployment, for most knowledge workers, the truth feels unclear. In this book, Sharon Gai cuts through the noise. Drawing from real-world examples and global insights, she explains how AI is reshaping the way we work-without hype or fearmongering. Instead of choosing between blind optimism or outright pessimism, she offers a practical, balanced perspective that helps readers make sense of the rapidly evolving AI landscape. You’ll learn how to: Reskill and future-proof your career in the face of AI disruption. Identify which parts of your role can be automated, and which require human creativity and judgment. Use proven frameworks to evaluate AI’s impact on your work and your organization. Apply actionable tips and tools to boost productivity, make smarter decisions, and do more with less. Gain clarity as a parent, leader, or professional navigating what this means for the next generation. Whether you’re an employee anxious about your future, a parent concerned about your children’s opportunities, or a leader managing a lean team with tight budgets, this book provides the strategies and mindset you need to adapt so you can stop worrying and start preparing. Offer Expires 6/30/2026.&lt;p style=&#34;text-align: center;height: 65px;margin-top: 40px&#34;&gt;&lt;a class=download style=&#34;background-color: #c8dbf7;border-color: #b0c4de;padding-top: 19px;text-decoration: none&#34; href=&#34;https://javacodegeeks.tradepub.com/c/pubRD.mpl?secure=1&amp;amp;sr=oc&amp;amp;_t=oc:&amp;amp;qf=w_wile891&amp;amp;ch=w_wile891-j&#34; target=_blank&gt;&lt;span style=&#34;font-size: 20px;font-weight: bold;vertical-align: middle&#34;&gt;Get it FREE!&lt;/span&gt;&lt;/a&gt;&lt;tr&gt;&lt;td width=25% style=&#34;border: 0px;vertical-align: top&#34;&gt;&lt;a href=&#34;https://javacodegeeks.tradepub.com/c/pubRD.mpl?secure=1&amp;amp;sr=oc&amp;amp;_t=oc:&amp;amp;qf=w_wile890&amp;amp;ch=w_wile890-j&#34; target=_blank&gt;&lt;img data-lazyloaded=1 src=https://img.tradepub.com/free/w_wile890/images/w_wile890c4.gif decoding=async data-src=https://img.tradepub.com/free/w_wile890/images/w_wile890c4.gif&gt;&lt;noscript&gt;&lt;img decoding=async src=https://img.tradepub.com/free/w_wile890/images/w_wile890c4.gif&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;td style=&#34;vertical-align: top;border: 0px&#34;&gt;&lt;h2 style=&#34;text-align: center;background: #c8dbf7&#34;&gt;90 Days to Level Up Your Leadership ($22.00 Value) FREE for a Limited Time&lt;/h2&gt;&lt;p&gt;Supercharge your leadership skills in just three months with expert advice from an industry leader. In 90 Days to Level Up Your Leadership, executive fellow at Harvard Business School and bestselling author Bill George will teach you how to become a better leader by focusing on a specific step each week. From laying the groundwork for your leadership journey all the way through to tackling contemporary leadership challenges, this book walks you through exactly how to develop your leadership skills, one step at a time. Inside you’ll find: A crystal-clear, week-by-week roadmap to help you improve your leadership skills. Actionable steps and practical tasks you can apply immediately to become a better leader. Tools to help you embrace and personify authentic leadership. If you’re ready to transform your career and achieve your goals in just one quarter, the 90 Days to Level Up series is for you. Whether you’re brand-new to a business, stepping into a leadership role for the first time, or looking to enhance your skills, this series will be your personal guide to unlocking your potential and reaching new professional heights. Offer Expires 6/30/2026.&lt;p style=&#34;text-align: center;height: 65px;margin-top: 40px&#34;&gt;&lt;a class=download style=&#34;background-color: #c8dbf7;border-color: #b0c4de;padding-top: 19px;text-decoration: none&#34; href=&#34;https://javacodegeeks.tradepub.com/c/pubRD.mpl?secure=1&amp;amp;sr=oc&amp;amp;_t=oc:&amp;amp;qf=w_wile890&amp;amp;ch=w_wile890-j&#34; target=_blank&gt;&lt;span style=&#34;font-size: 20px;font-weight: bold;vertical-align: middle&#34;&gt;Get it FREE!&lt;/span&gt;&lt;/a&gt;&lt;tr&gt;&lt;td width=25% style=&#34;border: 0px;vertical-align: top&#34;&gt;&lt;a href=&#34;https://javacodegeeks.tradepub.com/c/pubRD.mpl?secure=1&amp;amp;sr=oc&amp;amp;_t=oc:&amp;amp;qf=w_wile892&amp;amp;ch=w_wile892-j&#34; target=_blank&gt;&lt;img data-lazyloaded=1 src=https://img.tradepub.com/free/w_wile892/images/w_wile892c4.gif decoding=async data-src=https://img.tradepub.com/free/w_wile892/images/w_wile892c4.gif&gt;&lt;noscript&gt;&lt;img decoding=async src=https://img.tradepub.com/free/w_wile892/images/w_wile892c4.gif&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;td style=&#34;vertical-align: top;border: 0px&#34;&gt;&lt;h2 style=&#34;text-align: center;background: #c8dbf7&#34;&gt;Cloud Security Fundamentals: Building the Foundations for Secure Cloud Platforms ($131.95 Value) FREE for a Limited Time&lt;/h2&gt;&lt;p&gt;A hands-on toolkit for securing contemporary cloud environments. In Cloud Security Fundamentals: Building the Foundations for Secure Cloud Platforms, cybersecurity leader and educator, Jason Edwards, delivers a comprehensive guide to safeguarding data, applications, and infrastructure in the cloud. The author offers a complete walkthrough of cloud security, moving from foundational concepts to advanced, forward-looking practices. The book is filled with practical examples, hands-on guidance, and lessons drawn from real-world cloud security incidents and breaches. It equips readers with the tools and knowledge they need to defend against threats in cloud environments and how to understand coming developments in cloud technology that will impact organizations in all industries. Inside the book: A thorough introduction to cloud-native and advanced security practices for contemporary firms. A chapter on relevant cloud security certifications and professional growth advice. Practical discussions of foundational concepts in cloud security, including IAM, Zero Trust, and DevSecOps. Complete treatments of advanced cloud security themes, like leadership strategies, operational best practices, and techniques for dealing with common and emerging threats. Perfect for cloud security professionals, IT managers, and DevOps professionals, Cloud Security Fundamentals will also benefit system administrators, compliance and risk officers, consultants, auditors, and technology students in a variety of fields who require a foundational understanding of cloud security concepts.&lt;p style=&#34;text-align: center;height: 65px;margin-top: 40px&#34;&gt;&lt;a class=download style=&#34;background-color: #c8dbf7;border-color: #b0c4de;padding-top: 19px;text-decoration: none&#34; href=&#34;https://javacodegeeks.tradepub.com/c/pubRD.mpl?secure=1&amp;amp;sr=oc&amp;amp;_t=oc:&amp;amp;qf=w_wile892&amp;amp;ch=w_wile892-j&#34; target=_blank&gt;&lt;span style=&#34;font-size: 20px;font-weight: bold;vertical-align: middle&#34;&gt;Get it FREE!&lt;/span&gt;&lt;/a&gt;&lt;tr&gt;&lt;td width=25% style=&#34;border: 0px;vertical-align: top&#34;&gt;&lt;a href=&#34;https://javacodegeeks.tradepub.com/c/pubRD.mpl?secure=1&amp;amp;sr=oc&amp;amp;_t=oc:&amp;amp;qf=w_wile889&amp;amp;ch=w_wile889-j&#34; target=_blank&gt;&lt;img data-lazyloaded=1 src=https://img.tradepub.com/free/w_wile889/images/w_wile889c4.gif decoding=async data-src=https://img.tradepub.com/free/w_wile889/images/w_wile889c4.gif&gt;&lt;noscript&gt;&lt;img decoding=async src=https://img.tradepub.com/free/w_wile889/images/w_wile889c4.gif&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;td style=&#34;vertical-align: top;border: 0px&#34;&gt;&lt;h2 style=&#34;text-align: center;background: #c8dbf7&#34;&gt;The Vibe Coding Playbook: Building Your Tech Business with AI ($35.00 Value) FREE for a Limited Time&lt;/h2&gt;&lt;p&gt;A detailed and up-to-date walkthrough for entrepreneurs with limited (or non-existent) coding skills who want to build profitable software companies using new gen-AI tools. In The Vibe Coding Playbook: Building Your Tech Business With AI, renowned AI and data science educator Siraj Raval walks you through exactly what you need to do to build a technology business with generative AI-powered code assistants. Raval offers step-by-step guidance for non-technical professionals and entrepreneurs interested in creating scalable, profitable enterprises without spending years learning how to code. This book conceives of new artificial intelligence tools, like Cursor, as “co-founders,” lighting your way to constructing valuable software products and services. You’ll learn to build minimally viable products (MVPs), iterate on your software products as you develop and after launch, and grow your company while maintaining a lean, efficient, solopreneur-focused structure. Inside the book: Detailed guidance for entrepreneurs interested in creating powerful tech solutions for niche problems and markets without hiring expensive software developers. Strategies for using generative AI tools to substitute for traditional technical co-founders. Illustrative case studies from real-world founders who built successful technology businesses without learning to code. Useful tools for non-technical entrepreneurs, including prompt libraries, decision trees, QR codes linking to video tutorials demonstrating key techniques, and access to an exclusive online community of like-minded founders. Perfect for ambitious professionals and entrepreneurs who want to build a successful technology company now – using commercially available AI tools – The Vibe Coding Playbook is your personal roadmap to creating useful and profitable software for customers without learning how to code.&lt;p style=&#34;text-align: center;height: 65px;margin-top: 40px&#34;&gt;&lt;a class=download style=&#34;background-color: #c8dbf7;border-color: #b0c4de;padding-top: 19px;text-decoration: none&#34; href=&#34;https://javacodegeeks.tradepub.com/c/pubRD.mpl?secure=1&amp;amp;sr=oc&amp;amp;_t=oc:&amp;amp;qf=w_wile889&amp;amp;ch=w_wile889-j&#34; target=_blank&gt;&lt;span style=&#34;font-size: 20px;font-weight: bold;vertical-align: middle&#34;&gt;Get it FREE!&lt;/span&gt;&lt;/a&gt;&lt;tr&gt;&lt;td width=25% style=&#34;border: 0px;vertical-align: top&#34;&gt;&lt;a href=&#34;https://javacodegeeks.tradepub.com/c/pubRD.mpl?secure=1&amp;amp;sr=oc&amp;amp;_t=oc:&amp;amp;qf=w_wile888&amp;amp;ch=w_wile888-j&#34; target=_blank&gt;&lt;img data-lazyloaded=1 src=https://img.tradepub.com/free/w_wile888/images/w_wile888c4.gif decoding=async data-src=https://img.tradepub.com/free/w_wile888/images/w_wile888c4.gif&gt;&lt;noscript&gt;&lt;img decoding=async src=https://img.tradepub.com/free/w_wile888/images/w_wile888c4.gif&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;td style=&#34;vertical-align: top;border: 0px&#34;&gt;&lt;h2 style=&#34;text-align: center;background: #c8dbf7&#34;&gt;The Wellbeing Centered Workplace: 10 Strategies Fuelling Business Growth &amp;amp; Performance ($30.00 Value) FREE for a Limited Time&lt;/h2&gt;&lt;p&gt;A heartfelt personal journey that unlocks the power of evidence-based wellbeing at work. In The Wellbeing-Centered Workplace, Chris Cummings shares a powerful personal and professional journey following his partner’s mental health challenges that motivated him to quit his corporate career and start Wellbeing at Work, a global purpose-led business empowering organizations to prioritize employee wellbeing through community engagement, meaningful connections, and expert knowledge sharing. This book offers an honest account of how prioritizing wellbeing-both personal and organizational-became the cornerstone of sustainable growth, stronger leadership, and elevated team performance. Through real-world experiences, strategic insights, and lessons learned, the author reveals how wellbeing is not a soft skill but a strategic advantage that drives innovation, resilience, and results. Readers will also find 10 practical steps that organizations can take forward to create thriving workplaces, with each step supported by case studies from senior business leaders who have found standout success in a particular area. A must-read for leaders, entrepreneurs, and change-makers looking to build purpose-driven organizations where people and profits thrive together. In this book, readers will find discussion on: The huge benefits of flexibility in courting the global talent pool and how we can engage with wider communities. The unique desires of Millennials and Gen Z and the growing number of people taking career breaks or shifting to new careers in their fifties. How to ensure the human aspect in the workplace while complementing the rapidly developing technological landscape. The Wellbeing-Centered Workplaceis a practical, thought-provoking read for business leaders and managers to understand and adapt to the new world of work across every level of their organizations.&lt;p style=&#34;text-align: center;height: 65px;margin-top: 40px&#34;&gt;&lt;a class=download style=&#34;background-color: #c8dbf7;border-color: #b0c4de;padding-top: 19px;text-decoration: none&#34; href=&#34;https://javacodegeeks.tradepub.com/c/pubRD.mpl?secure=1&amp;amp;sr=oc&amp;amp;_t=oc:&amp;amp;qf=w_wile888&amp;amp;ch=w_wile888-j&#34; target=_blank&gt;&lt;span style=&#34;font-size: 20px;font-weight: bold;vertical-align: middle&#34;&gt;Get it FREE!&lt;/span&gt;&lt;/a&gt;&lt;tr&gt;&lt;td width=25% style=&#34;border: 0px;vertical-align: top&#34;&gt;&lt;a href=&#34;https://javacodegeeks.tradepub.com/c/pubRD.mpl?secure=1&amp;amp;sr=oc&amp;amp;_t=oc:&amp;amp;qf=w_wile884&amp;amp;ch=w_wile884-j&#34; target=_blank&gt;&lt;img data-lazyloaded=1 src=https://img.tradepub.com/free/w_wile884/images/w_wile884c4.gif decoding=async data-src=https://img.tradepub.com/free/w_wile884/images/w_wile884c4.gif&gt;&lt;noscript&gt;&lt;img decoding=async src=https://img.tradepub.com/free/w_wile884/images/w_wile884c4.gif&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;td style=&#34;vertical-align: top;border: 0px&#34;&gt;&lt;h2 style=&#34;text-align: center;background: #c8dbf7&#34;&gt;The Persuasion Engine: How Any Business Can Use AI-Powered Neuromarketing to Understand and Win Customers ($28.00 Value) FREE for a Limited Time&lt;/h2&gt;&lt;p&gt;Tap into your customers’ unconscious minds with cutting-edge AI and neuromarketing techniques. The Persuasion Engine, by neuromarketing and behavioral science expert Roger Dooley, solves the most pressing challenge faced by every marketer: how to figure out why customers make the decisions they do when 95% of their thought processes occur at an unconscious level. Dooley explains how artificial intelligence democratizes sophisticated neuromarketing tools that were once available only to Fortune 500 companies, making powerful customer insight and persuasion techniques accessible to businesses of any size. The book walks you through the evolution of traditional neuromarketing into “Neuromarketing 2.0,” where AI-powered tools eliminate the need for expensive lab studies and human behavioral science experts. It offers a comprehensive roadmap for implementing eye tracking, facial coding, biometrics, implicit testing, and advanced AI behavioral techniques that dramatically improve marketing effectiveness while reducing costs and time investment. Inside the book, you’ll find: Revolutionary AI prompting strategies that bring world-class behavioral science expertise to your desktop. Practical frameworks for leveraging attention, emotion, credibility, and decision architecture to boost conversions. Step-by-step guidance for implementing biometric tools and implicit testing without laboratory resources. Advanced techniques for creating scarcity, urgency, and FOMO that drive immediate customer action. Comprehensive methods for auditing and enhancing empathy in customer communications. Perfect for marketing professionals, business owners, entrepreneurs, and anyone with a stake in customer acquisition and retention, The Persuasion Engine provides actionable strategies that will transform your approach to marketing. Whether you’re working on a shoestring or managing enterprise campaigns, you’ll discover how to use your customers’ non-conscious motivations and create compelling marketing that work on real people in the real world. Offer Expires 6/24/2026.&lt;p style=&#34;text-align: center;height: 65px;margin-top: 40px&#34;&gt;&lt;a class=download style=&#34;background-color: #c8dbf7;border-color: #b0c4de;padding-top: 19px;text-decoration: none&#34; href=&#34;https://javacodegeeks.tradepub.com/c/pubRD.mpl?secure=1&amp;amp;sr=oc&amp;amp;_t=oc:&amp;amp;qf=w_wile884&amp;amp;ch=w_wile884-j&#34; target=_blank&gt;&lt;span style=&#34;font-size: 20px;font-weight: bold;vertical-align: middle&#34;&gt;Get it FREE!&lt;/span&gt;&lt;/a&gt;&lt;/table&gt;&lt;p&gt;That’s it for now, we hope you found them insightful. Stay tuned for more!&lt;p&gt;Till next time, keep geeking!&lt;/p&gt;&lt;style&gt;.lepopup-progress-60 div.lepopup-progress-t1&gt;div{background-color:#e0e0e0;}.lepopup-progress-60 div.lepopup-progress-t1&gt;div&gt;div{background-color:#bd4070;}.lepopup-progress-60 div.lepopup-progress-t1&gt;div&gt;div{color:#ffffff;}.lepopup-progress-60 div.lepopup-progress-t1&gt;label{color:#444444;}.lepopup-form-60, .lepopup-form-60 *, .lepopup-progress-60 {font-size:15px;color:#444444;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-signature-box span i{font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#555555;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-signature-box,.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;text&#39;],.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;email&#39;],.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;password&#39;],.lepopup-form-60 .lepopup-element div.lepopup-input select,.lepopup-form-60 .lepopup-element div.lepopup-input select option,.lepopup-form-60 .lepopup-element div.lepopup-input textarea{font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#555555;font-style:normal;text-decoration:none;text-align:left;background-color:rgba(255, 255, 255, 0.7);background-image:none;border-width:1px;border-style:solid;border-color:#cccccc;border-radius:0px;box-shadow: inset 0px 0px 15px -7px #000000;}.lepopup-form-60 .lepopup-element div.lepopup-input ::placeholder{color:#555555; opacity: 0.9;} .lepopup-form-60 .lepopup-element div.lepopup-input ::-ms-input-placeholder{color:#555555; opacity: 0.9;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect::-webkit-scrollbar-thumb{background-color:#cccccc;}.lepopup-form-60 .lepopup-element div.lepopup-input&gt;i.lepopup-icon-left, .lepopup-form-60 .lepopup-element div.lepopup-input&gt;i.lepopup-icon-right{font-size:20px;color:#444444;border-radius:0px;}.lepopup-form-60 .lepopup-element .lepopup-button,.lepopup-form-60 .lepopup-element .lepopup-button:visited{font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#ffffff;font-weight:700;font-style:normal;text-decoration:none;text-align:center;background-color:#326693;background-image:none;border-width:1px;border-style:solid;border-color:#326693;border-radius:0px;box-shadow:none;}.lepopup-form-60 .lepopup-element div.lepopup-input .lepopup-imageselect+label{border-width:1px;border-style:solid;border-color:#cccccc;border-radius:0px;box-shadow:none;}.lepopup-form-60 .lepopup-element div.lepopup-input .lepopup-imageselect+label span.lepopup-imageselect-label{font-size:15px;color:#444444;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl:checked+label:after{background-color:rgba(255, 255, 255, 0.7);}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-classic+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-fa-check+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-square+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl+label{background-color:rgba(255, 255, 255, 0.7);border-color:#cccccc;color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-square:checked+label:after{background-color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl:checked+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl+label:after{background-color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-classic+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-fa-check+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-dot+label{background-color:rgba(255, 255, 255, 0.7);border-color:#cccccc;color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-dot:checked+label:after{background-color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect&gt;input[type=&#39;checkbox&#39;]+label:hover{background-color:#bd4070;color:#ffffff;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect&gt;input[type=&#39;checkbox&#39;]:checked+label{background-color:#a93a65;color:#ffffff;}.lepopup-form-60 .lepopup-element input[type=&#39;checkbox&#39;].lepopup-tile+label, .lepopup-form-60 .lepopup-element input[type=&#39;radio&#39;].lepopup-tile+label {font-size:15px;color:#444444;font-style:normal;text-decoration:none;text-align:center;background-color:#ffffff;background-image:none;border-width:1px;border-style:solid;border-color:#cccccc;border-radius:0px;box-shadow:none;}.lepopup-form-60 .lepopup-element-error{font-size:15px;color:#ffffff;font-style:normal;text-decoration:none;text-align:left;background-color:#d9534f;background-image:none;}.lepopup-form-60 .lepopup-element-2 {background-color:rgba(226, 236, 250, 1);background-image:none;border-width:1px;border-style:solid;border-color:rgba(216, 216, 216, 1);border-radius:3px;box-shadow: 1px 1px 15px -6px #d7e1eb;}.lepopup-form-60 .lepopup-element-3 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:26px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-3 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:26px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-3 .lepopup-element-html-content {min-height:73px;}.lepopup-form-60 .lepopup-element-4 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:19px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-4 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:19px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-4 .lepopup-element-html-content {min-height:23px;}.lepopup-form-60 .lepopup-element-5 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-5 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-5 .lepopup-element-html-content {min-height:24px;}.lepopup-form-60 .lepopup-element-6 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-6 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-6 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-7 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-7 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-7 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-8 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-8 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-8 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-9 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-9 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-9 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-10 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-10 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-10 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-11 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-11 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-11 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-12 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-12 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-12 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-13 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-13 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-13 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-14 div.lepopup-input .lepopup-icon-left, .lepopup-form-60 .lepopup-element-14 div.lepopup-input .lepopup-icon-right {line-height:36px;}.lepopup-form-60 .lepopup-element-15 div.lepopup-input{height:auto;line-height:1;}.lepopup-form-60 .lepopup-element-16 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:14px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-16 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:14px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-16 .lepopup-element-html-content {min-height:5px;}.lepopup-form-60 .lepopup-element-19 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#333333;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-19 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#333333;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-19 .lepopup-element-html-content {min-height:363px;}.lepopup-form-60 .lepopup-element-0 * {font-size:15px;color:#ffffff;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-0 {font-size:15px;color:#ffffff;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:#5cb85c;background-image:none;border-width:0px;border-style:solid;border-color:#ccc;border-radius:5px;box-shadow: 1px 1px 15px -6px #000000;padding-top:40px;padding-right:40px;padding-bottom:40px;padding-left:40px;}.lepopup-form-60 .lepopup-element-0 .lepopup-element-html-content {min-height:160px;}&lt;/style&gt;&lt;div class=lepopup-inline style=&#34;margin: 0 auto;&#34;&gt;&lt;div class=&#34;lepopup-form lepopup-form-60 lepopup-form-OjZ4Rxrlxvlclm4I lepopup-form-icon-inside lepopup-form-position-middle-right&#34; data-session=0 data-id=OjZ4Rxrlxvlclm4I data-form-id=60 data-slug=7lQM6oyWL5bTm5lw data-title=&#34;Under the Post Inline&#34; data-page=1 data-xd=off data-width=820 data-height=430 data-position=middle-right data-esc=off data-enter=on data-disable-scrollbar=off style=display:none;width:820px;height:430px; onclick=event.stopPropagation();&gt;&lt;div class=lepopup-form-inner style=width:820px;height:430px;&gt;&lt;div class=&#34;lepopup-element lepopup-element-2 lepopup-element-rectangle&#34; data-type=rectangle data-top=0 data-left=0 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:501;top:0px;left:0px;width:820px;height:430px;&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-3 lepopup-element-html&#34; data-type=html data-top=7 data-left=10 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:502;top:7px;left:10px;width:797px;height:73px;&gt;&lt;div class=lepopup-element-html-content&gt;Do you want to know how to develop your skillset to become a &lt;span style=&#34;color: #CAB43D; text-shadow: 1px 1px #835D5D;&#34;&gt;Java Rockstar?&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-4 lepopup-element-html&#34; data-type=html data-top=83 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:503;top:83px;left:308px;width:473px;height:23px;&gt;&lt;div class=lepopup-element-html-content&gt;Subscribe to our newsletter to start Rocking &lt;span style=&#34;text-decoration: underline;&#34;&gt;right now!&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-5 lepopup-element-html&#34; data-type=html data-top=107 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:504;top:107px;left:308px;width:473px;height:24px;&gt;&lt;div class=lepopup-element-html-content&gt;To get you started we give you our best selling eBooks for &lt;span style=&#34;color:#e01404; text-shadow: 1px 1px #C99924; font-size: 15px;&#34;&gt;FREE!&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-6 lepopup-element-html&#34; data-type=html data-top=136 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:505;top:136px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;1.&lt;/span&gt; JPA Mini Book&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-7 lepopup-element-html&#34; data-type=html data-top=156 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:506;top:156px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;2.&lt;/span&gt; JVM Troubleshooting Guide&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-8 lepopup-element-html&#34; data-type=html data-top=176 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:507;top:176px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;3.&lt;/span&gt; JUnit Tutorial for Unit Testing&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-9 lepopup-element-html&#34; data-type=html data-top=196 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:508;top:196px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;4.&lt;/span&gt; Java Annotations Tutorial&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-10 lepopup-element-html&#34; data-type=html data-top=216 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:509;top:216px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;5.&lt;/span&gt; Java Interview Questions&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-11 lepopup-element-html&#34; data-type=html data-top=236 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:510;top:236px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;6.&lt;/span&gt; Spring Interview Questions&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-12 lepopup-element-html&#34; data-type=html data-top=256 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:511;top:256px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;7.&lt;/span&gt; Android UI Design&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-13 lepopup-element-html&#34; data-type=html data-top=282 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:512;top:282px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;and many more ....&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-14&#34; data-type=email data-deps data-id=14 data-top=305 data-left=308 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:513;top:305px;left:308px;width:473px;height:36px;&gt;&lt;div class=lepopup-input&gt;&lt;input type=email name=lepopup-14 class=lepopup-ta-left placeholder=&#34;Enter your e-mail...&#34; autocomplete=email data-default aria-label=&#34;Email Field&#34; oninput=lepopup_input_changed(this); onfocus=lepopup_input_error_hide(this);&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-15&#34; data-type=checkbox data-deps data-id=15 data-top=344 data-left=308 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:514;top:344px;left:308px;width:160px;&gt;&lt;div class=&#34;lepopup-input lepopup-cr-layout-1 lepopup-cr-layout-left&#34;&gt;&lt;div class=&#34;lepopup-cr-container lepopup-cr-container-medium lepopup-cr-container-left&#34;&gt;&lt;div class=lepopup-cr-box&gt;&lt;input class=&#34;lepopup-checkbox lepopup-checkbox-classic lepopup-checkbox-medium&#34; type=checkbox name=lepopup-15[] id=lepopup-checkbox-5Yu2ehDzii4SE9sf-14-0 value=on data-default=off onchange=lepopup_input_changed(this);&gt;&lt;label for=lepopup-checkbox-5Yu2ehDzii4SE9sf-14-0 onclick=lepopup_input_error_hide(this);&gt;&lt;/label&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-cr-label lepopup-ta-left&#34;&gt;&lt;label for=lepopup-checkbox-5Yu2ehDzii4SE9sf-14-0 onclick=lepopup_input_error_hide(this);&gt;&lt;/label&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-16 lepopup-element-html&#34; data-type=html data-top=344 data-left=338 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:515;top:344px;left:338px;width:350px;height:5px;&gt;&lt;div class=lepopup-element-html-content&gt;I agree to the &lt;a href=https://www.javacodegeeks.com/about/terms-of-use target=_blank&gt;Terms&lt;/a&gt; and &lt;a href=https://www.javacodegeeks.com/about/privacy-policy target=_blank&gt;Privacy Policy&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-17&#34; data-type=button data-top=372 data-left=308 data-animation-in=bounceIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:516;top:372px;left:308px;width:85px;height:37px;&gt;&lt;a class=&#34;lepopup-button lepopup-button-zoom-out&#34; href=https://www.javacodegeeks.com/feed/ onclick=&#34;return lepopup_submit(this);&#34; data-label=&#34;Sign up&#34; data-loading=Loading...&gt;&lt;span&gt;Sign up&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-19 lepopup-element-html&#34; data-type=html data-top=67 data-left=-15 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:518;top:67px;left:-15px;width:320px;height:363px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2015/01/books_promo.png fetchpriority=high decoding=async data-src=https://www.javacodegeeks.com/wp-content/uploads/2015/01/books_promo.png alt width=320 height=363&gt;&lt;noscript&gt;&lt;img fetchpriority=high decoding=async src=https://www.javacodegeeks.com/wp-content/uploads/2015/01/books_promo.png alt width=320 height=363&gt;&lt;/noscript&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-form lepopup-form-60 lepopup-form-OjZ4Rxrlxvlclm4I lepopup-form-icon-inside lepopup-form-position-middle-right&#34; data-session=0 data-id=OjZ4Rxrlxvlclm4I data-form-id=60 data-slug=7lQM6oyWL5bTm5lw data-title=&#34;Under the Post Inline&#34; data-page=confirmation data-xd=off data-width=420 data-height=320 data-position=middle-right data-esc=off data-enter=on data-disable-scrollbar=off style=display:none;width:420px;height:320px; onclick=event.stopPropagation();&gt;&lt;div class=lepopup-form-inner style=width:420px;height:320px;&gt;&lt;div class=&#34;lepopup-element lepopup-element-0 lepopup-element-html&#34; data-type=html data-top=80 data-left=70 data-animation-in=bounceInDown data-animation-out=fadeOutUp style=animation-duration:1000ms;animation-delay:0ms;z-index:500;top:80px;left:70px;width:280px;height:160px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;h4 style=&#34;text-align: center; font-size: 18px; font-weight: bold;&#34;&gt;Thank you!&lt;/h4&gt;&lt;p style=&#34;text-align: center;&#34;&gt;We will contact you soon.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;input type=hidden id=lepopup-logic-OjZ4Rxrlxvlclm4I value=[]&gt;&lt;/div&gt;&lt;div class=&#34;post-bottom-meta post-bottom-tags post-tags-classic&#34;&gt;&lt;div class=post-bottom-meta-title&gt;&lt;span class=tie-icon-tags aria-hidden=true&gt;&lt;/span&gt;Tags&lt;/div&gt;&lt;span class=tagcloud&gt;&lt;a href=https://www.javacodegeeks.com/tag/ebooks rel=tag&gt;eBooks&lt;/a&gt; &lt;a href=https://www.javacodegeeks.com/tag/offers rel=tag&gt;Offers&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div id=post-extra-info&gt;&lt;div class=theiaStickySidebar&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=clearfix&gt;&lt;/div&gt;</description>
      <author>Java Code Geeks</author>
      <guid>https://www.javacodegeeks.com/2026/06/free-ebooks-how-to-do-more-with-less-90-days-to-level-up-your-leadership-four-more-best-selling-titles-2.html</guid>
      <pubDate>Wed, 24 Jun 2026 10:30:30 +0000</pubDate>
    </item>
    <item>
      <title>GIS Map Service Introduction in Java</title>
      <link>https://www.javacodegeeks.com/gis-map-service-introduction-in-java.html</link>
      <description>&lt;header class=entry-header-outer&gt;&lt;nav id=breadcrumb&gt;&lt;a href=https://www.javacodegeeks.com/&gt;&lt;span class=tie-icon-home aria-hidden=true&gt;&lt;/span&gt;Home&lt;/a&gt;&lt;em class=delimiter&gt;»&lt;/em&gt;&lt;a href=https://www.javacodegeeks.com/category/java&gt;Java&lt;/a&gt;&lt;em class=delimiter&gt;»&lt;/em&gt;&lt;span class=current&gt;GIS Map Service Introduction in Java&lt;/span&gt;&lt;/nav&gt;&lt;div class=entry-header&gt;&lt;span class=post-cat-wrap&gt;&lt;a class=&#34;post-cat tie-cat-7&#34; href=https://www.javacodegeeks.com/category/java/core-java&gt;Core Java&lt;/a&gt;&lt;a class=&#34;post-cat tie-cat-9&#34; href=https://www.javacodegeeks.com/category/java/desktop-java&gt;Desktop Java&lt;/a&gt;&lt;a class=&#34;post-cat tie-cat-6&#34; href=https://www.javacodegeeks.com/category/java&gt;Java&lt;/a&gt;&lt;a class=&#34;post-cat tie-cat-15&#34; href=https://www.javacodegeeks.com/category/software-development&gt;Software Development&lt;/a&gt;&lt;/span&gt;&lt;h1 class=&#34;post-title entry-title&#34;&gt;GIS Map Service Introduction in Java&lt;/h1&gt;&lt;h2 class=entry-sub-title&gt;Java Map Service&lt;/h2&gt;&lt;/div&gt;&lt;/header&gt;&lt;div class=&#34;entry-content entry clearfix&#34;&gt;&lt;div class=&#34;stream-item stream-item-above-post-content&#34;&gt;&lt;div class=stream-item-size&gt;&lt;div id=adngin-in-post-0 style=&#34;float:left; margin-right:20px; margin-bottom:10px; width:300px; height:274px;&#34;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 class=wp-block-heading&gt;1. Introduction&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;You can see various map services like google maps, bing map and more in your ordinary life. This post describes how we start to build a GIS map service server and a simple WMS(Web Map Service) client using java. I will make a GIS map service with Honolulu GIS data. I also implement a simple map client for that in java open source based technologies such as GeoServer and geotools. The target system is running on Windows OS but you can also use other operating system like LINUX or UNIX and so on with a little effort.&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_5.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_5-1024x661.png fetchpriority=high decoding=async width=1024 height=661 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_5-1024x661.png alt class=wp-image-143965 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_5-1024x661.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_5-300x194.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_5-768x496.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_5.png 1383w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img fetchpriority=high decoding=async width=1024 height=661 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_5-1024x661.png alt class=wp-image-143965 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_5-1024x661.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_5-300x194.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_5-768x496.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_5.png 1383w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;h2 class=wp-block-heading&gt;2. GIS&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;GIS, which stands for Geospatial Information System, is a system that provides data about the real world we live in. This real-world information allows us to view and analyze regional data directly on a map, enabling better decision-making. This type of data possesses absolute positioning (coordinates) and elevation, making it inherently valid as independent system information.&lt;ul class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;Customers/Buildings:&lt;/strong&gt; Locations of retail stores or apartment complexes&lt;li&gt;&lt;strong&gt;Topography:&lt;/strong&gt; Elevation and relief of mountains and valleys (Altitude)&lt;li&gt;&lt;strong&gt;Hydrography:&lt;/strong&gt; Locations of rivers, oceans, and lakes&lt;li&gt;&lt;strong&gt;Roads:&lt;/strong&gt; Line data for highways, national roads, and alleys&lt;/ul&gt;&lt;p class=wp-block-paragraph&gt;Ultimately, GIS map service renders complex geographic data into visual maps, transforming it into actionable information that users can easily verify and analyze with their own eyes.&lt;h2 class=wp-block-heading&gt;3. Prerequisites&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;Our upcoming GIS map service will be implemented using Java. Consequently, several essential prerequisites are required. In this section, we will explore the necessary tools and environment setups needed to successfully build our map service.&lt;h3 class=wp-block-heading&gt;3.1. JDK&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;The map service client will be built using Java Swing. To support this, OpenJDK 17 or higher is required; however, for the purpose of this post, we will be using OpenJDK 21.&lt;figure class=&#34;wp-block-image size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/jdk21.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/jdk21.png decoding=async width=955 height=847 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/jdk21.png alt=&#34;download openJDK 21&#34; class=wp-image-143913 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/jdk21.png 955w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/jdk21-300x266.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/jdk21-768x681.png 768w&#34; data-sizes=&#34;(max-width: 955px) 100vw, 955px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=955 height=847 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/jdk21.png alt=&#34;download openJDK 21&#34; class=wp-image-143913 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/jdk21.png 955w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/jdk21-300x266.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/jdk21-768x681.png 768w&#34; sizes=&#34;(max-width: 955px) 100vw, 955px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;figcaption class=wp-element-caption&gt;Download openJDK 21&lt;/figcaption&gt;&lt;/figure&gt;&lt;p class=wp-block-paragraph&gt;After downloading the compressed file, we need to designate a directory to create our project, &lt;strong&gt;where&lt;/strong&gt; we will extract the files into the following folder to ensure consistency in installation and environment configuration&lt;pre class=wp-block-code&gt;&lt;code&gt;C:\DEV\Works\MapService&lt;/code&gt;&lt;/pre&gt;&lt;h3 class=wp-block-heading&gt;3.2. Maven&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;Downloading every single library used in this post one by one would be an overwhelming task for any developer. Therefore, we will define the required libraries in a Maven file, allowing them to be downloaded automatically to set up our development environment efficiently.&lt;figure class=&#34;wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex&#34;&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/maven.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/maven.png decoding=async width=957 height=844 data-id=143914 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/maven.png alt class=wp-image-143914 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/maven.png 957w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/maven-300x265.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/maven-768x677.png 768w&#34; data-sizes=&#34;(max-width: 957px) 100vw, 957px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=957 height=844 data-id=143914 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/maven.png alt class=wp-image-143914 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/maven.png 957w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/maven-300x265.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/maven-768x677.png 768w&#34; sizes=&#34;(max-width: 957px) 100vw, 957px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/figure&gt;&lt;p class=wp-block-paragraph&gt;To ensure consistency in our development environment, we will extract the downloaded file into the following directory.&lt;pre class=wp-block-code&gt;&lt;code&gt;C:\DEV\Works\MapService&lt;/code&gt;&lt;/pre&gt;&lt;h3 class=wp-block-heading&gt;3.3. Geotools&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;This is a famous open-source software that every GIS developer knows. It provides a vast array of libraries designed to make reading, writing, and rendering spatial data effortless. In the case of GeoTools, we will use the Maven repository to download it automatically. Using this library, we will build a simple GIS map service client.&lt;h3 class=wp-block-heading&gt;3.4. GeoServer&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;This is an open-source map server. To provide map services, we need a system capable of delivering geographic data. Specifically, these map servers read raw GIS data to serve it directly to clients or render it into map images. Accordingly, since we will be using the standalone version of GeoServer, please download it from the following site.&lt;figure class=&#34;wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-2 is-layout-flex wp-block-gallery-is-layout-flex&#34;&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/geoserver.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/geoserver.png decoding=async width=953 height=907 data-id=143915 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/geoserver.png alt=&#34;Geoserver Download Site&#34; class=wp-image-143915 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/geoserver.png 953w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/geoserver-300x286.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/geoserver-768x731.png 768w&#34; data-sizes=&#34;(max-width: 953px) 100vw, 953px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=953 height=907 data-id=143915 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/geoserver.png alt=&#34;Geoserver Download Site&#34; class=wp-image-143915 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/geoserver.png 953w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/geoserver-300x286.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/geoserver-768x731.png 768w&#34; sizes=&#34;(max-width: 953px) 100vw, 953px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/figure&gt;&lt;p class=wp-block-paragraph&gt;To ensure consistency in our development environment, we will extract the downloaded file into the following directory.&lt;pre class=wp-block-code&gt;&lt;code&gt;C:\DEV\Works\MapService&lt;/code&gt;&lt;/pre&gt;&lt;h2 class=wp-block-heading&gt;4. Selecting GIS Data for the Honolulu Region&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;To build a map service, GIS data is essential. However, since geographic data can contain sensitive information—such as military logistics or critical infrastructure—some countries heavily restrict its export or usage. Fortunately, there are several platforms that provide this data as open data. Specifically, we will be using the Honolulu dataset for our project.&lt;figure class=&#34;wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-3 is-layout-flex wp-block-gallery-is-layout-flex&#34;&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu.png decoding=async width=951 height=1013 data-id=143916 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu.png alt=&#34;Hololulu Open GIS Data Download&#34; class=wp-image-143916 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu.png 951w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu-282x300.png 282w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu-768x818.png 768w&#34; data-sizes=&#34;(max-width: 951px) 100vw, 951px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=951 height=1013 data-id=143916 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu.png alt=&#34;Hololulu Open GIS Data Download&#34; class=wp-image-143916 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu.png 951w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu-282x300.png 282w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu-768x818.png 768w&#34; sizes=&#34;(max-width: 951px) 100vw, 951px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/figure&gt;&lt;p class=wp-block-paragraph&gt;For instance, if only a single road were to be drawn on the map, it would be difficult to determine whether that line represents a road, a river, or some other feature. Therefore, for someone familiar with Honolulu to actually recognize the region, multiple layers are necessary. To this end, we have selected several key datasets as follows.&lt;figure class=wp-block-table&gt;&lt;table class=has-fixed-layout&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Data set&lt;td&gt;Description&lt;td&gt;&lt;tr&gt;&lt;td&gt;Building Footprint Centerpoints&lt;td&gt;Identifies locations of buildings on Oahu.&lt;td&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Building-Footprint-Centerpoints.png decoding=async width=955 height=1007 class=wp-image-143917 style=&#34;width: 150px&#34; data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Building-Footprint-Centerpoints.png alt=&#34;https://honolulu-cchnl.opendata.arcgis.com/datasets/fcab8c29b84a4e5f9f2cbf009d5ae012_4/explore?location=21.425220%2C-158.135029%2C15&#34; data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Building-Footprint-Centerpoints.png 955w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Building-Footprint-Centerpoints-285x300.png 285w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Building-Footprint-Centerpoints-768x810.png 768w&#34; data-sizes=&#34;(max-width: 955px) 100vw, 955px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=955 height=1007 class=wp-image-143917 style=&#34;width: 150px&#34; src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Building-Footprint-Centerpoints.png alt=&#34;https://honolulu-cchnl.opendata.arcgis.com/datasets/fcab8c29b84a4e5f9f2cbf009d5ae012_4/explore?location=21.425220%2C-158.135029%2C15&#34; srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Building-Footprint-Centerpoints.png 955w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Building-Footprint-Centerpoints-285x300.png 285w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Building-Footprint-Centerpoints-768x810.png 768w&#34; sizes=&#34;(max-width: 955px) 100vw, 955px&#34;&gt;&lt;/noscript&gt;&lt;tr&gt;&lt;td&gt;Zoning&lt;td&gt;Zoning designation boundaries from the City and County of Honolulu Zoning Code.&lt;td&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Zonin_honolulug.png decoding=async width=953 height=1009 class=wp-image-143918 style=&#34;width: 150px&#34; data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Zonin_honolulug.png alt=&#34;https://honolulu-cchnl.opendata.arcgis.com/datasets/b07278fbf1844df4a0ffcf5cf809fdf6_0/explore?location=21.471473%2C-157.977057%2C11&#34; data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Zonin_honolulug.png 953w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Zonin_honolulug-283x300.png 283w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Zonin_honolulug-768x813.png 768w&#34; data-sizes=&#34;(max-width: 953px) 100vw, 953px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=953 height=1009 class=wp-image-143918 style=&#34;width: 150px&#34; src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Zonin_honolulug.png alt=&#34;https://honolulu-cchnl.opendata.arcgis.com/datasets/b07278fbf1844df4a0ffcf5cf809fdf6_0/explore?location=21.471473%2C-157.977057%2C11&#34; srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Zonin_honolulug.png 953w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Zonin_honolulug-283x300.png 283w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Zonin_honolulug-768x813.png 768w&#34; sizes=&#34;(max-width: 953px) 100vw, 953px&#34;&gt;&lt;/noscript&gt;&lt;tr&gt;&lt;td&gt;Right of Way&lt;td&gt;The street Right of Ways that extend between parcels.&lt;td&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Right-of-Way.png decoding=async width=954 height=1007 class=wp-image-143919 style=&#34;width: 150px&#34; data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Right-of-Way.png alt=&#34;https://honolulu-cchnl.opendata.arcgis.com/datasets/1cb9cffc47fe4ba187a5d12aab95807a_0/explore?location=21.390258%2C-158.003147%2C14&#34; data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Right-of-Way.png 954w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Right-of-Way-284x300.png 284w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Right-of-Way-768x811.png 768w&#34; data-sizes=&#34;(max-width: 954px) 100vw, 954px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=954 height=1007 class=wp-image-143919 style=&#34;width: 150px&#34; src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Right-of-Way.png alt=&#34;https://honolulu-cchnl.opendata.arcgis.com/datasets/1cb9cffc47fe4ba187a5d12aab95807a_0/explore?location=21.390258%2C-158.003147%2C14&#34; srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Right-of-Way.png 954w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Right-of-Way-284x300.png 284w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Right-of-Way-768x811.png 768w&#34; sizes=&#34;(max-width: 954px) 100vw, 954px&#34;&gt;&lt;/noscript&gt;&lt;tr&gt;&lt;td&gt;Coastline&lt;td&gt;To reference the coastline for cartographic display.&lt;td&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Coastline.png decoding=async width=951 height=1006 class=wp-image-143920 style=&#34;width: 150px&#34; data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Coastline.png alt=&#34;https://honolulu-cchnl.opendata.arcgis.com/datasets/c8cb9f5779144de2b76c2441c8947c57_137/explore?location=21.443429%2C-157.987995%2C11&#34; data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Coastline.png 951w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Coastline-284x300.png 284w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Coastline-768x812.png 768w&#34; data-sizes=&#34;(max-width: 951px) 100vw, 951px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=951 height=1006 class=wp-image-143920 style=&#34;width: 150px&#34; src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Coastline.png alt=&#34;https://honolulu-cchnl.opendata.arcgis.com/datasets/c8cb9f5779144de2b76c2441c8947c57_137/explore?location=21.443429%2C-157.987995%2C11&#34; srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Coastline.png 951w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Coastline-284x300.png 284w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Coastline-768x812.png 768w&#34; sizes=&#34;(max-width: 951px) 100vw, 951px&#34;&gt;&lt;/noscript&gt;&lt;tr&gt;&lt;td&gt;Oahu Street Centerlines&lt;td&gt;To support common geographic and network analysis, routing and base mapping for City staff, Emergency Management, Homeland Security and Public Safety organizations&lt;td&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Oahu-Street-Centerlines.png decoding=async width=951 height=1006 class=wp-image-143921 style=&#34;width: 150px&#34; data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Oahu-Street-Centerlines.png alt=&#34;https://honolulu-cchnl.opendata.arcgis.com/datasets/6ced32082e9b4a108ae13bb5bc016ec3_0/explore?location=21.351537%2C-158.031295%2C13&#34; data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Oahu-Street-Centerlines.png 951w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Oahu-Street-Centerlines-284x300.png 284w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Oahu-Street-Centerlines-768x812.png 768w&#34; data-sizes=&#34;(max-width: 951px) 100vw, 951px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=951 height=1006 class=wp-image-143921 style=&#34;width: 150px&#34; src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Oahu-Street-Centerlines.png alt=&#34;https://honolulu-cchnl.opendata.arcgis.com/datasets/6ced32082e9b4a108ae13bb5bc016ec3_0/explore?location=21.351537%2C-158.031295%2C13&#34; srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Oahu-Street-Centerlines.png 951w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Oahu-Street-Centerlines-284x300.png 284w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Oahu-Street-Centerlines-768x812.png 768w&#34; sizes=&#34;(max-width: 951px) 100vw, 951px&#34;&gt;&lt;/noscript&gt;&lt;tr&gt;&lt;td&gt;Building Footprint&lt;td&gt;Building Footprint Centerpoints&lt;td&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Building-Footprint-Centerpoints-1.png decoding=async width=1616 height=1054 class=wp-image-143970 style=&#34;width: 150px&#34; data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Building-Footprint-Centerpoints-1.png alt data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Building-Footprint-Centerpoints-1.png 1616w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Building-Footprint-Centerpoints-1-300x196.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Building-Footprint-Centerpoints-1-1024x668.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Building-Footprint-Centerpoints-1-768x501.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Building-Footprint-Centerpoints-1-1536x1002.png 1536w&#34; data-sizes=&#34;(max-width: 1616px) 100vw, 1616px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1616 height=1054 class=wp-image-143970 style=&#34;width: 150px&#34; src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Building-Footprint-Centerpoints-1.png alt srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Building-Footprint-Centerpoints-1.png 1616w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Building-Footprint-Centerpoints-1-300x196.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Building-Footprint-Centerpoints-1-1024x668.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Building-Footprint-Centerpoints-1-768x501.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Building-Footprint-Centerpoints-1-1536x1002.png 1536w&#34; sizes=&#34;(max-width: 1616px) 100vw, 1616px&#34;&gt;&lt;/noscript&gt;&lt;tr&gt;&lt;td&gt;Zoning Map Boundary&lt;td&gt;Zoning Map Boundary&lt;td&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Zoning-Map-Boundary.png decoding=async width=1617 height=1050 class=wp-image-143971 style=&#34;width: 150px&#34; data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Zoning-Map-Boundary.png alt=&#34;Zoning Map Boundary of Honolulu&#34; data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Zoning-Map-Boundary.png 1617w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Zoning-Map-Boundary-300x195.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Zoning-Map-Boundary-1024x665.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Zoning-Map-Boundary-768x499.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Zoning-Map-Boundary-1536x997.png 1536w&#34; data-sizes=&#34;(max-width: 1617px) 100vw, 1617px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1617 height=1050 class=wp-image-143971 style=&#34;width: 150px&#34; src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Zoning-Map-Boundary.png alt=&#34;Zoning Map Boundary of Honolulu&#34; srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Zoning-Map-Boundary.png 1617w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Zoning-Map-Boundary-300x195.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Zoning-Map-Boundary-1024x665.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Zoning-Map-Boundary-768x499.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Zoning-Map-Boundary-1536x997.png 1536w&#34; sizes=&#34;(max-width: 1617px) 100vw, 1617px&#34;&gt;&lt;/noscript&gt;&lt;tr&gt;&lt;td&gt;All Parcels&lt;td&gt;All_Parcels of Honolulu&lt;td&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/All-parcels.png decoding=async width=1266 height=1007 class=wp-image-143974 style=&#34;width: 150px&#34; data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/All-parcels.png alt=&#34;All parcels of Honolulu&#34; data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/All-parcels.png 1266w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/All-parcels-300x239.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/All-parcels-1024x815.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/All-parcels-768x611.png 768w&#34; data-sizes=&#34;(max-width: 1266px) 100vw, 1266px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1266 height=1007 class=wp-image-143974 style=&#34;width: 150px&#34; src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/All-parcels.png alt=&#34;All parcels of Honolulu&#34; srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/All-parcels.png 1266w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/All-parcels-300x239.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/All-parcels-1024x815.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/All-parcels-768x611.png 768w&#34; sizes=&#34;(max-width: 1266px) 100vw, 1266px&#34;&gt;&lt;/noscript&gt;&lt;/table&gt;&lt;/figure&gt;&lt;h2 class=wp-block-heading&gt;5. Download GIS Data&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;There are various standard formats used to store geographic data. For development convenience, we plan to build a file-based service. Therefore, we will download and utilize SHP (Shapefile) format data—a standardized file format capable of storing GIS data—in a compressed archive format. As previously outlined in the data selection section, we have already chosen the Honolulu GIS datasets for our map service. You can follow the sequential steps below to download the data, and this exact process applies to all datasets identified in the previous section.&lt;ol class=wp-block-list&gt;&lt;li&gt;Visit https://honolulu-cchnl.opendata.arcgis.com/search&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu_download_site.png decoding=async width=952 height=1001 class=wp-image-143925 style=&#34;width: 450px&#34; data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu_download_site.png alt=&#34;Download Honolulu GIS Data&#34; data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu_download_site.png 952w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu_download_site-285x300.png 285w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu_download_site-768x808.png 768w&#34; data-sizes=&#34;(max-width: 952px) 100vw, 952px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=952 height=1001 class=wp-image-143925 style=&#34;width: 450px&#34; src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu_download_site.png alt=&#34;Download Honolulu GIS Data&#34; srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu_download_site.png 952w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu_download_site-285x300.png 285w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu_download_site-768x808.png 768w&#34; sizes=&#34;(max-width: 952px) 100vw, 952px&#34;&gt;&lt;/noscript&gt;&lt;li&gt;Use the keyword search; for example, type ‘Zoning’ to download Honolulu’s zoning data.&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu_zoning_search.png decoding=async width=955 height=1003 class=wp-image-143926 style=&#34;width: 450px&#34; data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu_zoning_search.png alt=&#34;Zoning GIS Data of Honolulu&#34; data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu_zoning_search.png 955w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu_zoning_search-286x300.png 286w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu_zoning_search-768x807.png 768w&#34; data-sizes=&#34;(max-width: 955px) 100vw, 955px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=955 height=1003 class=wp-image-143926 style=&#34;width: 450px&#34; src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu_zoning_search.png alt=&#34;Zoning GIS Data of Honolulu&#34; srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu_zoning_search.png 955w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu_zoning_search-286x300.png 286w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu_zoning_search-768x807.png 768w&#34; sizes=&#34;(max-width: 955px) 100vw, 955px&#34;&gt;&lt;/noscript&gt;&lt;li&gt;Click the Download button for the SHP file&lt;br&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu_zoning_shp_download.png decoding=async width=1058 height=1006 class=wp-image-143927 style=&#34;width: 450px&#34; data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu_zoning_shp_download.png alt=&#34;Download Zoning SHP file of Honolulu&#34; data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu_zoning_shp_download.png 1058w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu_zoning_shp_download-300x285.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu_zoning_shp_download-1024x974.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu_zoning_shp_download-768x730.png 768w&#34; data-sizes=&#34;(max-width: 1058px) 100vw, 1058px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1058 height=1006 class=wp-image-143927 style=&#34;width: 450px&#34; src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu_zoning_shp_download.png alt=&#34;Download Zoning SHP file of Honolulu&#34; srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu_zoning_shp_download.png 1058w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu_zoning_shp_download-300x285.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu_zoning_shp_download-1024x974.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/honolulu_zoning_shp_download-768x730.png 768w&#34; sizes=&#34;(max-width: 1058px) 100vw, 1058px&#34;&gt;&lt;/noscript&gt;&lt;/ol&gt;&lt;p class=wp-block-paragraph&gt;To maintain development environment consistency, we have extracted the downloaded archive files and stored the datasets inside the following folders.&lt;pre class=wp-block-code&gt;&lt;code&gt;C:\DEV\Works\MapService\data&lt;/code&gt;&lt;/pre&gt;&lt;figure class=&#34;wp-block-image size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/image.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/image.png decoding=async width=1017 height=624 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/image.png alt class=wp-image-143933 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/image.png 1017w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/image-300x184.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/image-768x471.png 768w&#34; data-sizes=&#34;(max-width: 1017px) 100vw, 1017px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1017 height=624 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/image.png alt class=wp-image-143933 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/image.png 1017w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/image-300x184.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/image-768x471.png 768w&#34; sizes=&#34;(max-width: 1017px) 100vw, 1017px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;h2 class=wp-block-heading&gt;6. GeoServer Configuration&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;For GeoServer, we assume that the downloaded &lt;code&gt;geoserver-2.28.4-bin.zip&lt;/code&gt; file has been extracted into the following directory, resulting in the folder &lt;code&gt;geoserver-2.28.4-bin&lt;/code&gt;.&lt;pre class=wp-block-code&gt;&lt;code&gt;C:\DEV\Works\MapService\geoserver-2.28.4-bin&lt;/code&gt;&lt;/pre&gt;&lt;p class=wp-block-paragraph&gt;Once inside that directory, navigate to the &lt;code&gt;bin&lt;/code&gt; folder and open the &lt;code&gt;startup.bat&lt;/code&gt; file. As long as the &lt;code&gt;JAVA_HOME&lt;/code&gt; variable is properly configured inside this file, GeoServer will launch without any issues. The procedure for specifying the &lt;code&gt;JAVA_HOME&lt;/code&gt; variable is as follows:&lt;ol class=wp-block-list&gt;&lt;li&gt;Open your favorite text editor&lt;li&gt;Open the &lt;code&gt;startup.bat&lt;/code&gt; file located in the &lt;code&gt;geoserver-2.28.4-bin\bin\&lt;/code&gt; directory.&lt;li&gt;Add the JAVA_HOME variable.&lt;/ol&gt;&lt;pre class=wp-block-code&gt;&lt;code&gt;@echo off&#xA;SET JAVA_HOME=C:\DEV\Works\MapService\jdk-21&lt;/code&gt;&lt;/pre&gt;&lt;p class=wp-block-paragraph&gt;Next, let’s run the &lt;code&gt;startup.bat&lt;/code&gt; file. If you see a screen like the one below, GeoServer has been launched successfully.&lt;figure class=&#34;wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-4 is-layout-flex wp-block-gallery-is-layout-flex&#34;&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/start_geoserver.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/start_geoserver.png decoding=async width=1025 height=633 data-id=143924 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/start_geoserver.png alt class=wp-image-143924 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/start_geoserver.png 1025w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/start_geoserver-300x185.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/start_geoserver-768x474.png 768w&#34; data-sizes=&#34;(max-width: 1025px) 100vw, 1025px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1025 height=633 data-id=143924 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/start_geoserver.png alt class=wp-image-143924 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/start_geoserver.png 1025w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/start_geoserver-300x185.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/start_geoserver-768x474.png 768w&#34; sizes=&#34;(max-width: 1025px) 100vw, 1025px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/figure&gt;&lt;h3 class=wp-block-heading&gt;6.1. Logging into GeoServer&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;As verified in the startup section, our GeoServer instance is now running. Let’s make sure the GeoServer Web Interface is working properly. You can access GeoServer using the following URL:&lt;pre class=wp-block-code&gt;&lt;code&gt;http://localhost:8080/geoserver&lt;/code&gt;&lt;/pre&gt;&lt;p class=wp-block-paragraph&gt;When you access the URL, the GeoServer Web Interface screen will appear as shown below.&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/geoserver_GUI.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/geoserver_GUI-1024x919.png decoding=async width=1024 height=919 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/geoserver_GUI-1024x919.png alt=&#34;Web interface of GeoServer&#34; class=wp-image-143928 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/geoserver_GUI-1024x919.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/geoserver_GUI-300x269.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/geoserver_GUI-768x689.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/geoserver_GUI.png 1061w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=919 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/geoserver_GUI-1024x919.png alt=&#34;Web interface of GeoServer&#34; class=wp-image-143928 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/geoserver_GUI-1024x919.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/geoserver_GUI-300x269.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/geoserver_GUI-768x689.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/geoserver_GUI.png 1061w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;figcaption class=wp-element-caption&gt;Web User Interface of GeoServer&lt;/figcaption&gt;&lt;/figure&gt;&lt;p class=wp-block-paragraph&gt;After installing GeoServer, the default username for the web interface is &lt;code&gt;admin&lt;/code&gt;, and its default password is &lt;code&gt;geoserver&lt;/code&gt;. Enter this username and password, then click the &lt;strong&gt;Login&lt;/strong&gt; button to perform your initial login as the administrator. Once logged in, the GeoServer configuration dashboard will appear as shown below.&lt;figure class=&#34;wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-5 is-layout-flex wp-block-gallery-is-layout-flex&#34;&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/geoserver_admin.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/geoserver_admin-1024x916.png decoding=async width=1024 height=916 data-id=143929 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/geoserver_admin-1024x916.png alt class=wp-image-143929 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/geoserver_admin-1024x916.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/geoserver_admin-300x268.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/geoserver_admin-768x687.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/geoserver_admin.png 1068w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=916 data-id=143929 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/geoserver_admin-1024x916.png alt class=wp-image-143929 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/geoserver_admin-1024x916.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/geoserver_admin-300x268.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/geoserver_admin-768x687.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/geoserver_admin.png 1068w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/login_geoserver.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/login_geoserver-1024x848.png decoding=async width=1024 height=848 data-id=143930 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/login_geoserver-1024x848.png alt class=wp-image-143930 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/login_geoserver-1024x848.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/login_geoserver-300x249.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/login_geoserver-768x636.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/login_geoserver.png 1055w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=848 data-id=143930 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/login_geoserver-1024x848.png alt class=wp-image-143930 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/login_geoserver-1024x848.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/login_geoserver-300x249.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/login_geoserver-768x636.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/login_geoserver.png 1055w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/figure&gt;&lt;h2 class=wp-block-heading&gt;7. Loading Honolulu GIS Data&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;Now, let’s load the Honolulu data into GeoServer. This process is essential for instructing GeoServer to ingest raw GIS data—in our case, Shapefiles (SHP)—and transform it into an active, ready-to-use map service.&lt;h3 class=wp-block-heading&gt;7.1. Loading Honolulu SHP Data&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;You can load the downloaded SHP files into GeoServer by following the procedures below.&lt;p class=wp-block-paragraph&gt;⚠️ IMPORTANT: Prior to uploading the Shapefile, verify that the dataset—including all companion extensions (.shp, .shx, .dbf, .prj)—resides in a specific server directory. All associated files must share an identical base name to ingest properly.&lt;h4 class=wp-block-heading&gt;1. Workspace Creation&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;First, we need to create a Workspace. A workspace acts as the top-level container (or namespace) for managing all your GIS data. You can create one by following the steps below:&lt;ol class=wp-block-list&gt;&lt;li&gt;Click on &lt;strong&gt;Workspaces&lt;/strong&gt; under the &lt;strong&gt;Data&lt;/strong&gt; section in the left-hand menu.&lt;li&gt;Click the &lt;strong&gt;Add new workspace&lt;/strong&gt; button located at the top.&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/add_workspace.png decoding=async width=1063 height=956 class=wp-image-143934 style=&#34;width: 450px&#34; data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/add_workspace.png alt=&#34;Add new workspace of Honolulu&#34; data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/add_workspace.png 1063w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/add_workspace-300x270.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/add_workspace-1024x921.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/add_workspace-768x691.png 768w&#34; data-sizes=&#34;(max-width: 1063px) 100vw, 1063px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1063 height=956 class=wp-image-143934 style=&#34;width: 450px&#34; src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/add_workspace.png alt=&#34;Add new workspace of Honolulu&#34; srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/add_workspace.png 1063w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/add_workspace-300x270.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/add_workspace-1024x921.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/add_workspace-768x691.png 768w&#34; sizes=&#34;(max-width: 1063px) 100vw, 1063px&#34;&gt;&lt;/noscript&gt;&lt;li&gt;Enter the following information and click the Save button.&lt;ul class=wp-block-list&gt;&lt;li&gt;Name: Honolulu&lt;li&gt;Namespace URI: https://honolulu-cchnl.opendata.arcgis.com/ &lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/name_namespace.png decoding=async width=1058 height=951 class=wp-image-143935 style=&#34;width: 450px&#34; data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/name_namespace.png alt=&#34;Add name and namespace of GeoServer&#34; data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/name_namespace.png 1058w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/name_namespace-300x270.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/name_namespace-1024x920.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/name_namespace-768x690.png 768w&#34; data-sizes=&#34;(max-width: 1058px) 100vw, 1058px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1058 height=951 class=wp-image-143935 style=&#34;width: 450px&#34; src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/name_namespace.png alt=&#34;Add name and namespace of GeoServer&#34; srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/name_namespace.png 1058w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/name_namespace-300x270.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/name_namespace-1024x920.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/name_namespace-768x690.png 768w&#34; sizes=&#34;(max-width: 1058px) 100vw, 1058px&#34;&gt;&lt;/noscript&gt;&lt;/ul&gt;&lt;/ol&gt;&lt;p class=wp-block-paragraph&gt;&lt;strong&gt;Note&lt;/strong&gt;: The Namespace URI does not need to be a live, active website. It is simply used as a unique identifier for your workspace.&lt;p class=wp-block-paragraph&gt;As shown below, you can verify that the “Honolulu” workspace has been successfully created.&lt;figure class=&#34;wp-block-image size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Honlulu_workspace.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Honlulu_workspace.png decoding=async width=812 height=553 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Honlulu_workspace.png alt class=wp-image-143937 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Honlulu_workspace.png 812w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Honlulu_workspace-300x204.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Honlulu_workspace-768x523.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Honlulu_workspace-220x150.png 220w&#34; data-sizes=&#34;(max-width: 812px) 100vw, 812px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=812 height=553 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Honlulu_workspace.png alt class=wp-image-143937 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Honlulu_workspace.png 812w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Honlulu_workspace-300x204.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Honlulu_workspace-768x523.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Honlulu_workspace-220x150.png 220w&#34; sizes=&#34;(max-width: 812px) 100vw, 812px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;h4 class=wp-block-heading&gt;2. Data Store Configuration and Shapefile Registration&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;In this step, we will link the actual file path of the Shapefile on your local computer to GeoServer. The procedure described below applies to all data generated and saved in the “GIS Data Selection” section. Therefore, please repeat this process for every individual SHP file you have.&lt;ol class=wp-block-list&gt;&lt;li&gt;Click on Stores under the Data section in the left-hand menu.&lt;li&gt;Click the Add new Store button located at the top.&lt;br&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_new_store.png decoding=async width=1061 height=955 class=wp-image-143939 style=&#34;width: 300px&#34; data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_new_store.png alt=&#34;Add New Data Store&#34; data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_new_store.png 1061w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_new_store-300x270.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_new_store-1024x922.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_new_store-768x691.png 768w&#34; data-sizes=&#34;(max-width: 1061px) 100vw, 1061px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1061 height=955 class=wp-image-143939 style=&#34;width: 300px&#34; src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_new_store.png alt=&#34;Add New Data Store&#34; srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_new_store.png 1061w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_new_store-300x270.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_new_store-1024x922.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_new_store-768x691.png 768w&#34; sizes=&#34;(max-width: 1061px) 100vw, 1061px&#34;&gt;&lt;/noscript&gt;&lt;li&gt;Select Shapefile from the Vector Data Sources list.&lt;br&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_SHP.png decoding=async width=1066 height=955 class=wp-image-143940 style=&#34;width: 300px&#34; data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_SHP.png alt=&#34;Add shp file data store&#34; data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_SHP.png 1066w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_SHP-300x269.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_SHP-1024x917.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_SHP-768x688.png 768w&#34; data-sizes=&#34;(max-width: 1066px) 100vw, 1066px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1066 height=955 class=wp-image-143940 style=&#34;width: 300px&#34; src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_SHP.png alt=&#34;Add shp file data store&#34; srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_SHP.png 1066w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_SHP-300x269.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_SHP-1024x917.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_SHP-768x688.png 768w&#34; sizes=&#34;(max-width: 1066px) 100vw, 1066px&#34;&gt;&lt;/noscript&gt;&lt;li&gt;Configure the Data Store information as follows:&lt;ul class=wp-block-list&gt;&lt;li&gt;Workspace: Honolulu (Select the workspace you created in Step 1)&lt;li&gt;Data Source Name: Building_Footprint_Centerpoints_SHP&lt;br&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/add_shp_name.png decoding=async width=1065 height=956 class=wp-image-143941 style=&#34;width: 300px&#34; data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/add_shp_name.png alt=&#34;Identify SHP data store&#34; data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/add_shp_name.png 1065w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/add_shp_name-300x269.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/add_shp_name-1024x919.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/add_shp_name-768x689.png 768w&#34; data-sizes=&#34;(max-width: 1065px) 100vw, 1065px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1065 height=956 class=wp-image-143941 style=&#34;width: 300px&#34; src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/add_shp_name.png alt=&#34;Identify SHP data store&#34; srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/add_shp_name.png 1065w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/add_shp_name-300x269.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/add_shp_name-1024x919.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/add_shp_name-768x689.png 768w&#34; sizes=&#34;(max-width: 1065px) 100vw, 1065px&#34;&gt;&lt;/noscript&gt;&lt;/ul&gt;&lt;li&gt;Configure the Connection Parameters (CRITICAL):&lt;ul class=wp-block-list&gt;&lt;li&gt;URL: Click the Browse… button, navigate to the directory on your server where the SHP files are stored, and select the target .shp file.&lt;li&gt;DBF charset: UTF-8.&lt;li&gt;Click the Save button at the bottom.&lt;br&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_SHP_connection.png decoding=async width=1061 height=956 class=wp-image-143942 style=&#34;width: 300px&#34; data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_SHP_connection.png alt=&#34;Add connection parameter for SHP data store&#34; data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_SHP_connection.png 1061w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_SHP_connection-300x270.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_SHP_connection-1024x923.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_SHP_connection-768x692.png 768w&#34; data-sizes=&#34;(max-width: 1061px) 100vw, 1061px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1061 height=956 class=wp-image-143942 style=&#34;width: 300px&#34; src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_SHP_connection.png alt=&#34;Add connection parameter for SHP data store&#34; srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_SHP_connection.png 1061w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_SHP_connection-300x270.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_SHP_connection-1024x923.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_SHP_connection-768x692.png 768w&#34; sizes=&#34;(max-width: 1061px) 100vw, 1061px&#34;&gt;&lt;/noscript&gt;&lt;/ul&gt;&lt;/ol&gt;&lt;h4 class=wp-block-heading&gt;3. Publishing a Layer and Configuring Spatial Reference&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;This is the final step to publish your map service to the web based on the saved data. First, you must verify that the data for our map service is successfully contained within the “Honolulu” workspace from Step 2, as shown below.&lt;div style=&#34;display:inline-block; margin: 15px 0;&#34;&gt;&lt;div id=adngin-JavaCodeGeeks_incontent_video-0 style=display:inline-block;&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;figure class=&#34;wp-block-image size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Honolulu_datastorea.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Honolulu_datastorea.png decoding=async width=961 height=544 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Honolulu_datastorea.png alt class=wp-image-143943 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Honolulu_datastorea.png 961w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Honolulu_datastorea-300x170.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Honolulu_datastorea-768x435.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Honolulu_datastorea-390x220.png 390w&#34; data-sizes=&#34;(max-width: 961px) 100vw, 961px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=961 height=544 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Honolulu_datastorea.png alt class=wp-image-143943 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Honolulu_datastorea.png 961w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Honolulu_datastorea-300x170.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Honolulu_datastorea-768x435.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Honolulu_datastorea-390x220.png 390w&#34; sizes=&#34;(max-width: 961px) 100vw, 961px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;p class=wp-block-paragraph&gt;Simply navigate to &lt;strong&gt;Layers&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Add a new resource&lt;/strong&gt; from the left-hand menu and select the corresponding data store.&lt;p class=wp-block-paragraph&gt;&lt;strong&gt;Note&lt;/strong&gt;: The procedure described below applies to all data generated and saved in the “GIS Data Selection” section. Therefore, please repeat this process for every individual SHP file.&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_new_layers.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_new_layers-1024x771.png decoding=async width=1024 height=771 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_new_layers-1024x771.png alt class=wp-image-143944 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_new_layers-1024x771.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_new_layers-300x226.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_new_layers-768x578.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_new_layers.png 1271w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=771 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_new_layers-1024x771.png alt class=wp-image-143944 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_new_layers-1024x771.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_new_layers-300x226.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_new_layers-768x578.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Add_new_layers.png 1271w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;ol class=wp-block-list&gt;&lt;li&gt;Select the workspace/store you want to publish from the dropdown menu.&lt;br&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Choose_1_layer.png decoding=async width=963 height=786 class=wp-image-143945 style=&#34;width: 450px&#34; data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Choose_1_layer.png alt=&#34;Select a data source for publishing&#34; data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Choose_1_layer.png 963w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Choose_1_layer-300x245.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Choose_1_layer-768x627.png 768w&#34; data-sizes=&#34;(max-width: 963px) 100vw, 963px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=963 height=786 class=wp-image-143945 style=&#34;width: 450px&#34; src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Choose_1_layer.png alt=&#34;Select a data source for publishing&#34; srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Choose_1_layer.png 963w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Choose_1_layer-300x245.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Choose_1_layer-768x627.png 768w&#34; sizes=&#34;(max-width: 963px) 100vw, 963px&#34;&gt;&lt;/noscript&gt;&lt;li&gt;Click the Publish link next to the SHP file name listed on the screen.&lt;br&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/publish_a_layer.png decoding=async width=955 height=683 class=wp-image-143946 style=&#34;width: 450px&#34; data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/publish_a_layer.png alt=&#34;Publishing a layer&#34; data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/publish_a_layer.png 955w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/publish_a_layer-300x215.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/publish_a_layer-768x549.png 768w&#34; data-sizes=&#34;(max-width: 955px) 100vw, 955px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=955 height=683 class=wp-image-143946 style=&#34;width: 450px&#34; src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/publish_a_layer.png alt=&#34;Publishing a layer&#34; srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/publish_a_layer.png 955w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/publish_a_layer-300x215.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/publish_a_layer-768x549.png 768w&#34; sizes=&#34;(max-width: 955px) 100vw, 955px&#34;&gt;&lt;/noscript&gt;&lt;li&gt;On the Edit Layer page, configure the following mandatory fields:&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Edit_a_layer.png decoding=async width=958 height=788 class=wp-image-143947 style=&#34;width: 450px&#34; data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Edit_a_layer.png alt=&#34;Edit some spatial parameters&#34; data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Edit_a_layer.png 958w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Edit_a_layer-300x247.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Edit_a_layer-768x632.png 768w&#34; data-sizes=&#34;(max-width: 958px) 100vw, 958px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=958 height=788 class=wp-image-143947 style=&#34;width: 450px&#34; src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Edit_a_layer.png alt=&#34;Edit some spatial parameters&#34; srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Edit_a_layer.png 958w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Edit_a_layer-300x247.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Edit_a_layer-768x632.png 768w&#34; sizes=&#34;(max-width: 958px) 100vw, 958px&#34;&gt;&lt;/noscript&gt;&lt;li&gt;Coordinate Reference Systems (공간 참조계)&lt;ul class=wp-block-list&gt;&lt;li&gt;In most cases, GeoServer will automatically detect and configure the coordinate system. However, if the coordinate system for your SHP file is not automatically detected, click the &lt;strong&gt;Find…&lt;/strong&gt; button next to &lt;strong&gt;Declared SRS&lt;/strong&gt;, search for the correct EPSG code, and select it.&lt;br&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Coordinate-Reference-System.png decoding=async width=1274 height=463 class=wp-image-143948 style=&#34;width: 450px&#34; data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Coordinate-Reference-System.png alt=&#34;Set a coordinate reference system or Find it manually&#34; data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Coordinate-Reference-System.png 1274w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Coordinate-Reference-System-300x109.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Coordinate-Reference-System-1024x372.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Coordinate-Reference-System-768x279.png 768w&#34; data-sizes=&#34;(max-width: 1274px) 100vw, 1274px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1274 height=463 class=wp-image-143948 style=&#34;width: 450px&#34; src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Coordinate-Reference-System.png alt=&#34;Set a coordinate reference system or Find it manually&#34; srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Coordinate-Reference-System.png 1274w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Coordinate-Reference-System-300x109.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Coordinate-Reference-System-1024x372.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Coordinate-Reference-System-768x279.png 768w&#34; sizes=&#34;(max-width: 1274px) 100vw, 1274px&#34;&gt;&lt;/noscript&gt;&lt;/ul&gt;&lt;li&gt;Bounding Boxes&lt;ul class=wp-block-list&gt;&lt;li&gt;You must compute the bounding boxes so GeoServer can recognize the spatial extent of your map. Simply click the buttons in the following order to let GeoServer calculate them automatically:&lt;li&gt;Click &lt;strong&gt;Compute from data&lt;/strong&gt; (Calculates the bounding box from the raw data).&lt;li&gt;Click &lt;strong&gt;Compute from native bounds&lt;/strong&gt; (Calculates the spatial extent bounds).&lt;br&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/BoundingBoxes.png decoding=async width=961 height=339 class=wp-image-143949 style=&#34;width: 450px&#34; data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/BoundingBoxes.png alt=&#34;Calculating a bounding boxes of a layer.&#34; data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/BoundingBoxes.png 961w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/BoundingBoxes-300x106.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/BoundingBoxes-768x271.png 768w&#34; data-sizes=&#34;(max-width: 961px) 100vw, 961px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=961 height=339 class=wp-image-143949 style=&#34;width: 450px&#34; src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/BoundingBoxes.png alt=&#34;Calculating a bounding boxes of a layer.&#34; srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/BoundingBoxes.png 961w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/BoundingBoxes-300x106.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/BoundingBoxes-768x271.png 768w&#34; sizes=&#34;(max-width: 961px) 100vw, 961px&#34;&gt;&lt;/noscript&gt;&lt;/ul&gt;&lt;/ol&gt;&lt;h4 class=wp-block-heading&gt;4. Completion and Verification (Layer Preview)&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;Click the &lt;strong&gt;Save&lt;/strong&gt; button at the very bottom of the page to complete the data loading and publishing process. To verify that your layer has been successfully published, click on &lt;strong&gt;Layer Preview&lt;/strong&gt; at the very top of the left-hand menu. Find the name of the layer you just published (e.g., &lt;code&gt;honolulu:layer_name&lt;/code&gt;), and click the &lt;strong&gt;OpenLayers&lt;/strong&gt; link on the right. A new window will open, and you will see your SHP file beautifully visualized as a live map!&lt;figure class=&#34;wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-6 is-layout-flex wp-block-gallery-is-layout-flex&#34;&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Layer_Preview.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Layer_Preview-1024x767.png decoding=async width=1024 height=767 data-id=143950 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Layer_Preview-1024x767.png alt class=wp-image-143950 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Layer_Preview-1024x767.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Layer_Preview-300x225.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Layer_Preview-768x575.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Layer_Preview.png 1264w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=767 data-id=143950 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Layer_Preview-1024x767.png alt class=wp-image-143950 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Layer_Preview-1024x767.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Layer_Preview-300x225.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Layer_Preview-768x575.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Layer_Preview.png 1264w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Layer_preview_openlayers.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Layer_preview_openlayers-1024x935.png decoding=async width=1024 height=935 data-id=143951 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Layer_preview_openlayers-1024x935.png alt class=wp-image-143951 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Layer_preview_openlayers-1024x935.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Layer_preview_openlayers-300x274.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Layer_preview_openlayers-768x701.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Layer_preview_openlayers.png 1044w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=935 data-id=143951 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Layer_preview_openlayers-1024x935.png alt class=wp-image-143951 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Layer_preview_openlayers-1024x935.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Layer_preview_openlayers-300x274.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Layer_preview_openlayers-768x701.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Layer_preview_openlayers.png 1044w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/figure&gt;&lt;p class=wp-block-paragraph&gt;Once you have added layers for all the datasets from the “GIS Data Selection” section, you can search and verify the list of added layers as shown below.&lt;figure class=&#34;wp-block-image size-large is-style-default&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Layer_List.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Layer_List-1024x713.png decoding=async width=1024 height=713 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Layer_List-1024x713.png alt class=wp-image-143952 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Layer_List-1024x713.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Layer_List-300x209.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Layer_List-768x534.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Layer_List.png 1394w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=713 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Layer_List-1024x713.png alt class=wp-image-143952 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Layer_List-1024x713.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Layer_List-300x209.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Layer_List-768x534.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Layer_List.png 1394w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;p class=wp-block-paragraph&gt;Now, we have successfully completed the data loading process for the Honolulu regional GIS map service. The next step is to verify whether the web service we created has been generated and deployed correctly..&lt;h2 class=wp-block-heading&gt;8. Understanding Web Map Services&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;We decided to use data from the Honolulu area for our map service. Viewing a map of Honolulu essentially means overlaying and combining multiple layers of data into a single, cohesive view, as shown below. The data we have downloaded and processed so far represents only a tiny fraction of that entire ecosystem.&lt;figure class=&#34;wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-7 is-layout-flex wp-block-gallery-is-layout-flex&#34;&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Zonin_honolulug.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Zonin_honolulug.png decoding=async width=953 height=1009 data-id=143918 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Zonin_honolulug.png alt=&#34;https://honolulu-cchnl.opendata.arcgis.com/datasets/b07278fbf1844df4a0ffcf5cf809fdf6_0/explore?location=21.471473%2C-157.977057%2C11&#34; class=wp-image-143918 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Zonin_honolulug.png 953w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Zonin_honolulug-283x300.png 283w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Zonin_honolulug-768x813.png 768w&#34; data-sizes=&#34;(max-width: 953px) 100vw, 953px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=953 height=1009 data-id=143918 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/Zonin_honolulug.png alt=&#34;https://honolulu-cchnl.opendata.arcgis.com/datasets/b07278fbf1844df4a0ffcf5cf809fdf6_0/explore?location=21.471473%2C-157.977057%2C11&#34; class=wp-image-143918 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/Zonin_honolulug.png 953w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Zonin_honolulug-283x300.png 283w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/Zonin_honolulug-768x813.png 768w&#34; sizes=&#34;(max-width: 953px) 100vw, 953px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;figcaption class=wp-element-caption&gt;Zoning&lt;/figcaption&gt;&lt;/figure&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/gis_lsyer_stack.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/gis_lsyer_stack.png decoding=async width=704 height=769 data-id=143969 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/gis_lsyer_stack.png alt class=wp-image-143969 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/gis_lsyer_stack.png 704w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/gis_lsyer_stack-275x300.png 275w&#34; data-sizes=&#34;(max-width: 704px) 100vw, 704px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=704 height=769 data-id=143969 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/gis_lsyer_stack.png alt class=wp-image-143969 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/gis_lsyer_stack.png 704w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/gis_lsyer_stack-275x300.png 275w&#34; sizes=&#34;(max-width: 704px) 100vw, 704px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/figure&gt;&lt;ul class=wp-block-list&gt;&lt;li&gt;Building Footprint Centerpoints&lt;li&gt;Zoning&lt;li&gt;Right of Way&lt;li&gt;Coastline&lt;li&gt;Oahu Street Centerlines&lt;li&gt;Building Footprint Centerpoints&lt;li&gt;Zoning Map Boundary&lt;li&gt;All Parcels&lt;/ul&gt;&lt;p class=wp-block-paragraph&gt;To display this geospatial data, it is necessary to examine the GIS map service defined by the OGC (Open Geospatial Consortium), which serves as the industry standard.&lt;h3 class=wp-block-heading&gt;8.1. WMS(Web Map Service)&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;WMS(Web Map Service) is a standard protocol that renders GIS data into map images (such as PNG or JPEG) on the server side and serves them to the web.&lt;ul class=wp-block-list&gt;&lt;li&gt;Requires a slight processing overhead as images are generated by the server on demand.&lt;li&gt;Reflects real-time data modifications instantly since the server queries the live data source for every request.&lt;/ul&gt;&lt;h3 class=wp-block-heading&gt;8.2. WFS(Web Feature Service)&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;A standard protocol that retrieves raw vector datasets (geographic features and attributes) from the server, allowing the client to handle the rendering and data processing.&lt;ul class=wp-block-list&gt;&lt;li&gt;Increases client-side complexity and computational load, as the client application is responsible for rendering large amounts of coordinate data.&lt;li&gt;Supports advanced GIS capabilities, enabling clients to query, manipulate, and directly edit/update (WFS-T) the underlying geospatial data attributes.&lt;/ul&gt;&lt;h3 class=wp-block-heading&gt;8.3. WPS(Web Process Service)&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;WPS provides client access to pre-defined spatial data processing algorithms and analytical functions (e.g., buffering, intersection, spatial analysis) on the server side.&lt;ul class=wp-block-list&gt;&lt;li&gt;Enables highly customized geospatial services tailored specifically to complex user business logic and rules.&lt;li&gt;Increases server-side computational load and architectural complexity exponentially as the business logic and analytical rules become more intricate.&lt;/ul&gt;&lt;h3 class=wp-block-heading&gt;8.4. WMTS(Web Map Tile Service)&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;WMTS serves pre-rendered, cached map tiles partitioned by predefined grids and LOD (Level of Detail) scales to maximize web map delivery performance.&lt;ul class=wp-block-list&gt;&lt;li&gt;Guarantees exceptionally fast loading speeds by serving optimized, small-sized static image tiles instead of rendering on the fly.&lt;li&gt;Widely adopted as the industry standard by major global map providers, including Google Maps and Bing Maps.&lt;li&gt;Introduces a data reflection delay (near real-time) since changes in the raw spatial data require re-generating or purging the cached tiles.&lt;/ul&gt;&lt;h2 class=wp-block-heading&gt;9. Simple WMS Client Application &lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;To verify and interact with the Honolulu geospatial data we configured earlier, we will build a simple WMS client application. We will implement this GIS map service client using the robust capabilities provided by the open-source GeoTools library.&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/image-1.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/image-1-1024x294.png decoding=async width=1024 height=294 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/image-1-1024x294.png alt class=wp-image-144011 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/image-1-1024x294.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/image-1-300x86.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/image-1-768x220.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/image-1.png 1029w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=294 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/image-1-1024x294.png alt class=wp-image-144011 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/image-1-1024x294.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/image-1-300x86.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/image-1-768x220.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/image-1.png 1029w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;p class=wp-block-paragraph&gt;When it comes to WMS, the behavior of a GIS map service client is actually very simple.&lt;ul class=wp-block-list&gt;&lt;li&gt;It invokes the WMS service to check what kind of GIS map services are currently available.&lt;li&gt;Then, it simply requests the specific map image it wants from the WMS list.&lt;/ul&gt;&lt;p class=wp-block-paragraph&gt;Although you can merge multiple map layers into a single view, handling this feature is beyond the scope of this post. I will make sure to explain it in detail in the next article.&lt;h3 class=wp-block-heading&gt;9.1. Configuring the Client Environment&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;First, to ensure consistency and proper environment configuration, we will set up our map service client in the following folder.&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: plain; title: ; notranslate&#34;&gt;C:\DEV\Works\MapService\MapClient&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;h4 class=wp-block-heading&gt;1. Batch File Configuration&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;To configure the Maven environment, the following two environment variables are required:&lt;ul class=wp-block-list&gt;&lt;li&gt;&lt;code&gt;JAVA_HOME&lt;/code&gt;: The installation path of the downloaded OpenJDK 21.&lt;li&gt;&lt;code&gt;MVN_HOME&lt;/code&gt;: The installation path of the downloaded Apache Maven.&lt;/ul&gt;&lt;p class=wp-block-paragraph&gt;To streamline this setup, we have created a batch file named &lt;code&gt;setenv.bat&lt;/code&gt; as shown below:&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: plain; title: ; notranslate&#34;&gt;SET JAVA_HOME=C:\DEV\Works\MapService\jdk-21&#xA;SET MVN_HOME=C:\DEV\Works\MapService\apache-maven-3.9.16&#xA;&#xA;SET PATH=%JAVA_HOME%\BIN;%MVN_HOME%\BIN;%PATH%;&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;h4 class=wp-block-heading&gt;2. Executing the Batch File&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;Open a Windows Command Prompt (cmd) window, navigate to the project directory, and enter &lt;code&gt;setenv.bat&lt;/code&gt; as shown below.&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/open_cmd-2.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/open_cmd-2-1024x749.png decoding=async width=1024 height=749 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/open_cmd-2-1024x749.png alt class=wp-image-143957 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/open_cmd-2-1024x749.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/open_cmd-2-300x219.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/open_cmd-2-768x562.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/open_cmd-2.png 1181w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=749 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/open_cmd-2-1024x749.png alt class=wp-image-143957 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/open_cmd-2-1024x749.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/open_cmd-2-300x219.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/open_cmd-2-768x562.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/open_cmd-2.png 1181w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;h4 class=wp-block-heading&gt;3. Verifying the Maven Environment&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;Run the Maven version check command as shown below. If the output displays the exact Maven version you downloaded, your map service client environment configuration is successfully complete.&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/mvn_version.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/mvn_version-1024x453.png decoding=async width=1024 height=453 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/mvn_version-1024x453.png alt class=wp-image-143958 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/mvn_version-1024x453.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/mvn_version-300x133.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/mvn_version-768x340.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/mvn_version.png 1110w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=453 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/mvn_version-1024x453.png alt class=wp-image-143958 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/mvn_version-1024x453.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/mvn_version-300x133.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/mvn_version-768x340.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/mvn_version.png 1110w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;h3 class=wp-block-heading&gt;9.2. Configuring the Client Development Environment&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;First, create a &lt;code&gt;pom.xml&lt;/code&gt; file as shown below to configure the project packages and manage the GeoTools library dependencies.&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: xml; title: ; notranslate&#34;&gt;&amp;lt;project xmlns=&amp;#34;http://maven.apache.org/POM/4.0.0&amp;#34;&#xA;         xmlns:xsi=&amp;#34;http://www.w3.org/2001/XMLSchema-instance&amp;#34;&#xA;         xsi:schemaLocation=&amp;#34;http://maven.apache.org/POM/4.0.0&#xA;         https://maven.apache.org/xsd/maven-4.0.0.xsd&amp;#34;&amp;gt;&#xA;&#xA;    &amp;lt;modelVersion&amp;gt;4.0.0&amp;lt;/modelVersion&amp;gt;&#xA;&#xA;    &amp;lt;groupId&amp;gt;com.honolulu.gis&amp;lt;/groupId&amp;gt;&#xA;    &amp;lt;artifactId&amp;gt;map-client&amp;lt;/artifactId&amp;gt;&#xA;    &amp;lt;version&amp;gt;1.0.0&amp;lt;/version&amp;gt;&#xA;&#xA;    &amp;lt;properties&amp;gt;&#xA;        &amp;lt;maven.compiler.source&amp;gt;21&amp;lt;/maven.compiler.source&amp;gt;&#xA;        &amp;lt;maven.compiler.target&amp;gt;21&amp;lt;/maven.compiler.target&amp;gt;&#xA;        &amp;lt;geotools.version&amp;gt;32.2&amp;lt;/geotools.version&amp;gt;&#xA;    &amp;lt;/properties&amp;gt;&#xA;&#xA;    &amp;lt;repositories&amp;gt;&#xA;        &amp;lt;repository&amp;gt;&#xA;            &amp;lt;id&amp;gt;osgeo&amp;lt;/id&amp;gt;&#xA;            &amp;lt;url&amp;gt;https://repo.osgeo.org/repository/release/&amp;lt;/url&amp;gt;&#xA;        &amp;lt;/repository&amp;gt;&#xA;    &amp;lt;/repositories&amp;gt;&#xA;&#xA;    &amp;lt;dependencies&amp;gt;&#xA;&#xA;        &amp;lt;dependency&amp;gt;&#xA;            &amp;lt;groupId&amp;gt;org.geotools&amp;lt;/groupId&amp;gt;&#xA;            &amp;lt;artifactId&amp;gt;gt-main&amp;lt;/artifactId&amp;gt;&#xA;            &amp;lt;version&amp;gt;${geotools.version}&amp;lt;/version&amp;gt;&#xA;        &amp;lt;/dependency&amp;gt;&#xA;&#xA;        &amp;lt;dependency&amp;gt;&#xA;            &amp;lt;groupId&amp;gt;org.geotools&amp;lt;/groupId&amp;gt;&#xA;            &amp;lt;artifactId&amp;gt;gt-wms&amp;lt;/artifactId&amp;gt;&#xA;            &amp;lt;version&amp;gt;${geotools.version}&amp;lt;/version&amp;gt;&#xA;        &amp;lt;/dependency&amp;gt;&#xA;&#xA;    &amp;lt;/dependencies&amp;gt;&#xA;&#xA;    &amp;lt;build&amp;gt;&#xA;        &amp;lt;plugins&amp;gt;&#xA;&#xA;            &amp;lt;plugin&amp;gt;&#xA;                &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;&#xA;                &amp;lt;artifactId&amp;gt;maven-compiler-plugin&amp;lt;/artifactId&amp;gt;&#xA;                &amp;lt;version&amp;gt;3.13.0&amp;lt;/version&amp;gt;&#xA;            &amp;lt;/plugin&amp;gt;&#xA;&#xA;            &amp;lt;plugin&amp;gt;&#xA;                &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;&#xA;                &amp;lt;artifactId&amp;gt;maven-shade-plugin&amp;lt;/artifactId&amp;gt;&#xA;                &amp;lt;version&amp;gt;3.5.3&amp;lt;/version&amp;gt;&#xA;&#xA;                &amp;lt;executions&amp;gt;&#xA;                    &amp;lt;execution&amp;gt;&#xA;                        &amp;lt;phase&amp;gt;package&amp;lt;/phase&amp;gt;&#xA;                        &amp;lt;goals&amp;gt;&#xA;                            &amp;lt;goal&amp;gt;shade&amp;lt;/goal&amp;gt;&#xA;                        &amp;lt;/goals&amp;gt;&#xA;&#xA;                        &amp;lt;configuration&amp;gt;                           &amp;lt;createDependencyReducedPom&amp;gt;false&amp;lt;/createDependencyReducedPom&amp;gt;&#xA;&#xA;                            &amp;lt;filters&amp;gt;&#xA;                                &amp;lt;filter&amp;gt;&#xA;                                    &amp;lt;artifact&amp;gt;*:*&amp;lt;/artifact&amp;gt;&#xA;                                    &amp;lt;excludes&amp;gt;&#xA;                                        &amp;lt;exclude&amp;gt;META-INF/*.SF&amp;lt;/exclude&amp;gt;&#xA;                                        &amp;lt;exclude&amp;gt;META-INF/*.RSA&amp;lt;/exclude&amp;gt;&#xA;                                        &amp;lt;exclude&amp;gt;META-INF/*.DSA&amp;lt;/exclude&amp;gt;&#xA;                                    &amp;lt;/excludes&amp;gt;&#xA;                                &amp;lt;/filter&amp;gt;&#xA;                            &amp;lt;/filters&amp;gt;&#xA;&#xA;                            &amp;lt;transformers&amp;gt;&#xA;&#xA;                                &amp;lt;transformer implementation=&#xA;                                        &amp;#34;org.apache.maven.plugins.shade.resource.ServicesResourceTransformer&amp;#34;/&amp;gt;&#xA;&#xA;                                &amp;lt;transformer implementation=&#xA;                                        &amp;#34;org.apache.maven.plugins.shade.resource.ManifestResourceTransformer&amp;#34;&amp;gt;&#xA;&#xA;                                    &amp;lt;mainClass&amp;gt;&#xA;                                        com.honolulu.gis.Main&#xA;                                    &amp;lt;/mainClass&amp;gt;&#xA;                                &amp;lt;/transformer&amp;gt;&#xA;                            &amp;lt;/transformers&amp;gt;&#xA;                        &amp;lt;/configuration&amp;gt;&#xA;                    &amp;lt;/execution&amp;gt;&#xA;                &amp;lt;/executions&amp;gt;&#xA;            &amp;lt;/plugin&amp;gt;&#xA;        &amp;lt;/plugins&amp;gt;&#xA;    &amp;lt;/build&amp;gt;&#xA;&amp;lt;/project&amp;gt;&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;p class=wp-block-paragraph&gt;Subsequently, execute the &lt;code&gt;mvn install&lt;/code&gt; command to validate the integrity of the build and ensure the absence of configuration errors. Upon a successful verification check, the system will autonomously resolve and download the necessary dependency artifacts, as depicted in the diagram below.&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/mvn_install.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/mvn_install-1024x806.png decoding=async width=1024 height=806 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/mvn_install-1024x806.png alt class=wp-image-143959 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/mvn_install-1024x806.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/mvn_install-300x236.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/mvn_install-768x605.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/mvn_install.png 1129w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=806 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/mvn_install-1024x806.png alt class=wp-image-143959 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/mvn_install-1024x806.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/mvn_install-300x236.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/mvn_install-768x605.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/mvn_install.png 1129w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;h3 class=wp-block-heading&gt;9.3. Establishing the Maven Source Directory Layout&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;To align with standard development practices, we will configure the Maven directory layout and provision the required folders to initialize the execution environment for the Java map service client application.&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: plain; title: ; notranslate&#34;&gt;MapClient/                       (Project Root)&#xA; ├── src/&#xA; │    ├── main/&#xA; │    │    ├── java/             (Java source code root)&#xA; │    │    │    └── com/&#xA; │    │    │         └── honolulu/&#xA; │    │    │              └── gis/&#xA; │    │    │                   ├── Main.java      (Application entry point)&#xA; │    │    │                   ├── MainFrame.java (Main GUI window container)&#xA; │    │    │                   ├── MapPanel.java  (Dedicated map rendering screen)&#xA; │    │    │                   ├── GeoServerClient.java (WMS connection &amp;amp;amp; communication handler)&#xA; │    │    │                   └── WmsLayerInfo.java (Data model for WMS layer metadata)&#xA; │    │    └── resources/        (Application resources and configurations)&#xA; │    │         └── logback.xml  (Optional: Logging framework configuration)&#xA; │    └── test/                  (Unit test source root)&#xA; │         └── java/&#xA; └── pom.xml             (Project object model for dependencies and build setup)&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;p class=wp-block-paragraph&gt;Please place and create the project folder structure within our designated workspace directory as shown below.&lt;pre class=wp-block-code&gt;&lt;code&gt;C:\DEV\Works\MapService&lt;/code&gt;&lt;/pre&gt;&lt;h2 class=wp-block-heading&gt;10. Implementing the GeoServer WMS Client&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;All setups and environment configurations are now complete. It is time to implement the Java source code inside our established project directory.&lt;p class=wp-block-paragraph&gt;The architecture consists of the &lt;code&gt;MainFrame&lt;/code&gt; class as the primary UI window container. The core functionality is driven by two main components: &lt;code&gt;GeoServerClient&lt;/code&gt;, which communicates with GeoServer to fetch map graphics via WMS, and &lt;code&gt;MapPanel&lt;/code&gt;, which renders those retrieved map images onto the screen. This section provides a detailed breakdown and explanation of each source file.&lt;h3 class=wp-block-heading&gt;10.1. The Main Class&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;The &lt;code&gt;Main&lt;/code&gt; class serves as the application entry point. It handles the secure initialization of the graphical user interface.&lt;ul class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;Event Dispatch Thread (EDT) Safety&lt;/strong&gt;: By utilizing &lt;code&gt;SwingUtilities.invokeLater()&lt;/code&gt;, the application guarantees that the creation and manipulation of Swing UI components are executed strictly on the single-threaded Event Dispatch Thread, preventing potential concurrency or rendering anomalies.&lt;li&gt;&lt;strong&gt;Main Window Lifecycle&lt;/strong&gt;: It instantiates the top-level UI container, &lt;code&gt;MainFrame&lt;/code&gt;, and invokes &lt;code&gt;setVisible(true)&lt;/code&gt; to render it visible to the end user.&lt;/ul&gt;&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: java; title: ; notranslate&#34;&gt;package com.honolulu.gis;&#xA;&#xA;import javax.swing.*;&#xA;&#xA;public class Main {&#xA;&#xA;    public static void main(&#xA;            String[] args) {&#xA;&#xA;        SwingUtilities.invokeLater(&#xA;                () -&amp;gt; {&#xA;                    try {&#xA;                        MainFrame frame = new MainFrame();&#xA;                        frame.setVisible(true);&#xA;                    } catch (Exception e) {&#xA;                        e.printStackTrace();&#xA;                    }&#xA;                }&#xA;        );&#xA;    }&#xA;}&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;h3 class=wp-block-heading&gt;10.2. The &lt;code&gt;MainFrame&lt;/code&gt; Class&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;&lt;code&gt;MainFrame&lt;/code&gt; extends &lt;code&gt;JFrame&lt;/code&gt; and acts as the central coordinator of the application. It manages UI layout partitioning, layer data modeling, and WMS state transitions.&lt;ul class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;Split Layout Architecture&lt;/strong&gt;: It implements a &lt;code&gt;JSplitPane&lt;/code&gt; with a divider to isolate concerns:&lt;ul class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;Left Pane (&lt;code&gt;createTree()&lt;/code&gt;)&lt;/strong&gt;: Displays a hierarchical tree view of remote GIS metadata layers.&lt;li&gt;&lt;strong&gt;Right Pane (&lt;code&gt;mapPanel&lt;/code&gt;)&lt;/strong&gt;: Hosts the customized image component designated for geospatial canvas rendering.&lt;/ul&gt;&lt;/ul&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_5.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_5-1024x661.png decoding=async width=1024 height=661 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_5-1024x661.png alt=&#34;WMS GIS Map Service Client&#34; class=wp-image-143965 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_5-1024x661.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_5-300x194.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_5-768x496.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_5.png 1383w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=661 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_5-1024x661.png alt=&#34;WMS GIS Map Service Client&#34; class=wp-image-143965 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_5-1024x661.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_5-300x194.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_5-768x496.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_5.png 1383w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;ul class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;Stream-driven Layer Categorization&lt;/strong&gt;:&lt;ul class=wp-block-list&gt;&lt;li&gt;The &lt;code&gt;createTree()&lt;/code&gt; method consumes list metadata from &lt;code&gt;client.loadLayers()&lt;/code&gt;.&lt;li&gt;It leverages Java Streams to filter for targets matching the &lt;strong&gt;“Honolulu”&lt;/strong&gt; namespace, groups them efficiently using &lt;code&gt;Collectors.groupingBy()&lt;/code&gt;, and builds a robust component hierarchy using &lt;code&gt;DefaultMutableTreeNode&lt;/code&gt;.&lt;/ul&gt;&lt;/ul&gt;&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: java; title: ; notranslate&#34;&gt;public class GeoServerClient {&#xA;    private final String wmsUrl;&#xA;    private WebMapServer server;&#xA;&#xA;    public GeoServerClient(String wmsUrl) throws Exception {&#xA;        this.wmsUrl = wmsUrl;&#xA;&#xA;        server = new WebMapServer(new URL(&#xA;            wmsUrl + &amp;#34;?service=WMS&amp;amp;request=GetCapabilities&amp;#34;&#xA;        ));&#xA;    }&#x9;&#xA;&#x9;&#xA;&#x9;...&#xA;&#x9;&#xA;&#x9;public List&amp;lt;WmsLayerInfo&amp;gt; loadLayers() {&#xA;        List&amp;lt;WmsLayerInfo&amp;gt; result = new ArrayList&amp;lt;&amp;gt;();&#xA;        collect(server.getCapabilities().getLayer(), result);&#xA;        return result;&#xA;    }&#xA;&#x9;&#xA;&#x9;...&#xA;}&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;ul class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;Asynchronous Selection and Map Refreshment&lt;/strong&gt;:&lt;ul class=wp-block-list&gt;&lt;li&gt;A &lt;code&gt;TreeSelectionListener&lt;/code&gt; continuously monitors user interactions. When a user selects a valid &lt;code&gt;WmsLayerInfo&lt;/code&gt; leaf node, the application updates the active &lt;code&gt;selectedLayers&lt;/code&gt; cache.&lt;li&gt;The &lt;code&gt;refreshMap()&lt;/code&gt; mechanism queries the GeoServer backend to parse the target layer bounds (&lt;strong&gt;BBox&lt;/strong&gt;) and spatial reference system (&lt;strong&gt;CRS&lt;/strong&gt;). It automatically calculates dimensions based on the current &lt;code&gt;mapPanel&lt;/code&gt; viewport scale and dispatches a WMS &lt;code&gt;GetMap&lt;/code&gt; transaction, dynamically mapping the incoming buffer stream straight to the canvas display.&lt;/ul&gt;&lt;/ul&gt;&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: java; title: ; notranslate&#34;&gt;package com.honolulu.gis;&#xA;&#xA;import javax.swing.*;&#xA;import javax.swing.tree.*;&#xA;import java.awt.*;&#xA;import java.util.*;&#xA;import java.util.List;&#xA;import java.util.stream.Collectors;&#xA;&#xA;public class MainFrame extends JFrame {&#xA;&#xA;    private final MapPanel mapPanel =&#xA;            new MapPanel();&#xA;&#xA;    private final Set&amp;lt;String&amp;gt; selectedLayers =&#xA;            new HashSet&amp;lt;&amp;gt;();&#xA;&#xA;    private final GeoServerClient client;&#xA;&#xA;    public MainFrame() throws Exception {&#xA;        client &#xA;          = new GeoServerClient(                                                                 &amp;#34;http://localhost:8080/geoserver/wms&amp;#34;);&#xA;&#xA;        setTitle(&amp;#34;GeoServer WMS Client&amp;#34;);&#xA;&#xA;        setSize(1400,900);&#xA;&#xA;        setDefaultCloseOperation(&#xA;                JFrame.EXIT_ON_CLOSE&#xA;        );&#xA;&#xA;        JSplitPane split =&#xA;                new JSplitPane();&#xA;&#xA;        split.setDividerLocation(300);&#xA;&#xA;        split.setLeftComponent(&#xA;                createTree()&#xA;        );&#xA;&#xA;        split.setRightComponent(&#xA;                mapPanel&#xA;        );&#xA;&#xA;        add(split);&#xA;    }&#xA;&#xA;    private JScrollPane createTree()&#xA;            throws Exception {&#xA;&#xA;        List&amp;lt;WmsLayerInfo&amp;gt; layers =&#xA;                client.loadLayers();&#xA;&#xA;        DefaultMutableTreeNode root =&#xA;                new DefaultMutableTreeNode(&#xA;                        &amp;#34;Layers&amp;#34;&#xA;                );&#xA;        //Filter &amp;#39;Honolulu&amp;#39; namespace only&#xA;        Map&amp;lt;String, List&amp;lt;WmsLayerInfo&amp;gt;&amp;gt; grouped =&#xA;&#x9;&#x9;&#x9;layers.stream()&#xA;                .filter(l -&amp;gt; &amp;#34;Honolulu&amp;#34;.equals(l.namespace()))&#xA;                .collect(Collectors.groupingBy(WmsLayerInfo::namespace));&#xA;&#xA;        for(var entry : grouped.entrySet()) {&#xA;&#xA;            DefaultMutableTreeNode ns =&#xA;                    new DefaultMutableTreeNode(&#xA;                            entry.getKey()&#xA;                    );&#xA;&#xA;            for(var layer : entry.getValue()) {&#xA;&#xA;                ns.add(&#xA;                        new DefaultMutableTreeNode(&#xA;                                layer&#xA;                        )&#xA;                );&#xA;            }&#xA;&#xA;            root.add(ns);&#xA;        }&#xA;&#xA;        JTree tree =&#xA;                new JTree(root);&#xA;&#xA;        tree.addTreeSelectionListener(e -&amp;gt; {&#xA;&#xA;            Object node =&#xA;                    ((DefaultMutableTreeNode)&#xA;                            tree.getLastSelectedPathComponent())&#xA;                            .getUserObject();&#xA;&#xA;            if(node instanceof WmsLayerInfo layer) {&#xA;&#xA;                try {&#xA;&#xA;                    selectedLayers.clear();&#xA;&#xA;                    selectedLayers.add(&#xA;                            layer.name()&#xA;                    );&#xA;&#xA;                    refreshMap();&#xA;&#xA;                } catch (Exception ex) {&#xA;                    ex.printStackTrace();&#xA;                }&#xA;            }&#xA;        });&#xA;&#xA;        return new JScrollPane(tree);&#xA;    }&#xA;&#xA;    private void refreshMap()&#xA;            throws Exception {&#xA;&#xA;&#x9;&#x9;GeoServerClient.BBoxInfo binfo = client.getBoundsFromLayers(new ArrayList&amp;lt;&amp;gt;(selectedLayers));&#xA;&#x9;&#x9;String bbox = binfo.bbox;&#xA;&#x9;&#x9;String crs = binfo.crs;&#xA;&#x9;&#x9;var image =&#xA;&#x9;&#x9;&#x9;&#x9;client.getMap(&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&#x9;new ArrayList&amp;lt;&amp;gt;(selectedLayers), // String OK&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&#x9;bbox,crs,&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&#x9;mapPanel.getWidth(),&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&#x9;mapPanel.getHeight()&#xA;&#x9;&#x9;&#x9;&#x9;);&#xA;&#xA;        mapPanel.setImage(image);&#xA;    }&#xA;}&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;h3 class=wp-block-heading&gt;10.3. The &lt;code&gt;GeoServerClient&lt;/code&gt; Class&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;The &lt;code&gt;GeoServerClient&lt;/code&gt; class serves as the dedicated network interface controller that manages OGC WMS transactions with the remote GeoServer container using the &lt;strong&gt;GeoTools&lt;/strong&gt; API capabilities.&lt;ul class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;Capabilities Lifecycle Initialization&lt;/strong&gt;:&lt;ul class=wp-block-list&gt;&lt;li&gt;The constructor accepts the root WMS endpoint and instantiates a &lt;strong&gt;&lt;code&gt;WebMapServer&lt;/code&gt;&lt;/strong&gt; component by issuing an implicit &lt;code&gt;GetCapabilities&lt;/code&gt; metadata handshake. This caches the entire server capabilities tree schema in application storage upon startup.&lt;/ul&gt;&lt;/ul&gt;&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: java; title: ; notranslate&#34;&gt;server = new WebMapServer(new URL(&#xA;    wmsUrl + &amp;#34;?service=WMS&amp;amp;request=GetCapabilities&amp;#34;&#xA; ));&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;ul class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;Automated Bounding Box (BBox) and CRS Retrieval&lt;/strong&gt;:&lt;ul class=wp-block-list&gt;&lt;li&gt;The &lt;code&gt;getBoundsFromLayers()&lt;/code&gt; routine automates spatial boundary detection. It queries the target mapping layer properties, retrieves the primary Coordinate Reference System (&lt;strong&gt;CRS&lt;/strong&gt;), maps it to a GeoTools &lt;strong&gt;&lt;code&gt;CRSEnvelope&lt;/code&gt;&lt;/strong&gt;, and serializes the lower/upper bounds into a standard comma-delimited bounding box coordinate string (&lt;code&gt;&amp;#34;minx,miny,maxx,maxy&amp;#34;&lt;/code&gt;).&lt;/ul&gt;&lt;li&gt;Recursive Metadata Tree Traversal (&lt;code&gt;loadLayers()&lt;/code&gt; &amp;amp; &lt;code&gt;collect&lt;/code&gt;()):&lt;ul class=wp-block-list&gt;&lt;li&gt;GeoServer layers inherently possess nested hierarchical characteristics. To resolve this, the client deploys a &lt;strong&gt;recursive algorithm&lt;/strong&gt; within the &lt;code&gt;collect()&lt;/code&gt; function.&lt;li&gt;It runs depth-first searches across all &lt;code&gt;getLayerChildren()&lt;/code&gt; arrays, splits namespace domains by identifying character colons (&lt;code&gt;:&lt;/code&gt;), and constructs an iterable list model containing sanitized &lt;code&gt;WmsLayerInfo&lt;/code&gt; records.&lt;/ul&gt;&lt;li&gt;&lt;strong&gt;Dynamic WMS &lt;code&gt;GetMap&lt;/code&gt; Compilation&lt;/strong&gt;:&lt;ul class=wp-block-list&gt;&lt;li&gt;The &lt;code&gt;getMap()&lt;/code&gt; function compiles raw viewport geometries directly into compliant WMS URL specifications.&lt;li&gt;It binds array collections, spatial boundaries (&lt;code&gt;bbox&lt;/code&gt;), spatial references (&lt;code&gt;srs&lt;/code&gt;), and target output resolutions (&lt;code&gt;width&lt;/code&gt;, &lt;code&gt;height&lt;/code&gt;) into a query pipeline.&lt;li&gt;By piping this connection stream through &lt;strong&gt;&lt;code&gt;ImageIO.read()&lt;/code&gt;&lt;/strong&gt;, it smoothly captures the pixel-perfect &lt;code&gt;image/png&lt;/code&gt; response and maps it seamlessly into an immutable native &lt;strong&gt;&lt;code&gt;BufferedImage&lt;/code&gt;&lt;/strong&gt; layer context.&lt;/ul&gt;&lt;/ul&gt;&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: java; title: ; notranslate&#34;&gt;package com.honolulu.gis;&#xA;&#xA;import org.geotools.ows.wms.Layer;&#xA;import org.geotools.ows.wms.WebMapServer;&#xA;import org.geotools.ows.wms.WMSCapabilities;&#xA;import org.geotools.geometry.jts.ReferencedEnvelope;&#xA;import org.geotools.ows.wms.CRSEnvelope;&#xA;&#xA;import javax.imageio.ImageIO;&#xA;import java.awt.image.BufferedImage;&#xA;import java.net.URL;&#xA;import java.util.ArrayList;&#xA;import java.util.List;&#xA;&#xA;&#xA;public class GeoServerClient {&#xA;&#xA;    private final String wmsUrl;&#xA;&#xA;    private WebMapServer server;&#xA;&#xA;    public GeoServerClient(String wmsUrl) throws Exception {&#xA;        this.wmsUrl = wmsUrl;&#xA;&#xA;        server = new WebMapServer(new URL(&#xA;                wmsUrl + &amp;#34;?service=WMS&amp;amp;request=GetCapabilities&amp;#34;&#xA;        ));&#xA;    }&#xA;&#x9;&#xA;&#x9;public static class BBoxInfo {&#xA;&#x9;&#x9;public String bbox;&#xA;&#x9;&#x9;public String crs;&#xA;&#x9;}&#xA;&#x9;&#xA;&#x9;public BBoxInfo getBoundsFromLayers(List&amp;lt;String&amp;gt; layers) {&#xA;&#xA;&#x9;&#x9;Layer layer = findLayerByName(layers.get(0));&#xA;&#xA;&#x9;&#x9;var map = layer.getBoundingBoxes();&#xA;&#xA;&#x9;&#x9;String crs = map.keySet().iterator().next();&#xA;&#x9;&#x9;CRSEnvelope env = map.get(crs);&#xA;&#xA;&#x9;&#x9;double minx = env.getLowerCorner().getOrdinate(0);&#xA;&#x9;&#x9;double miny = env.getLowerCorner().getOrdinate(1);&#xA;&#x9;&#x9;double maxx = env.getUpperCorner().getOrdinate(0);&#xA;&#x9;&#x9;double maxy = env.getUpperCorner().getOrdinate(1);&#xA;&#xA;&#x9;&#x9;BBoxInfo info = new BBoxInfo();&#xA;&#x9;&#x9;info.bbox = minx + &amp;#34;,&amp;#34; + miny + &amp;#34;,&amp;#34; + maxx + &amp;#34;,&amp;#34; + maxy;&#xA;&#x9;&#x9;info.crs = crs;&#xA;&#xA;&#x9;&#x9;return info;&#xA;&#x9;}&#xA;&#x9;&#xA;    public List&amp;lt;WmsLayerInfo&amp;gt; loadLayers() {&#xA;&#xA;        List&amp;lt;WmsLayerInfo&amp;gt; result = new ArrayList&amp;lt;&amp;gt;();&#xA;&#xA;        collect(server.getCapabilities().getLayer(), result);&#xA;&#xA;        return result;&#xA;    }&#xA;&#xA;    private void collect(Layer layer, List&amp;lt;WmsLayerInfo&amp;gt; result) {&#xA;&#xA;        if (layer.getName() != null) {&#xA;&#xA;            String ns = &amp;#34;&amp;#34;;&#xA;&#xA;            if (layer.getName().contains(&amp;#34;:&amp;#34;)) {&#xA;                ns = layer.getName().split(&amp;#34;:&amp;#34;)[0];&#xA;            }&#xA;&#xA;            result.add(new WmsLayerInfo(&#xA;                    ns,&#xA;                    layer.getName(),&#xA;                    layer.getTitle()&#xA;            ));&#xA;        }&#xA;&#xA;        for (Layer c : layer.getLayerChildren()) {&#xA;            collect(c, result);&#xA;        }&#xA;    }&#xA;&#x9;&#xA;&#x9;private org.geotools.ows.wms.Layer findLayerByName(String name) {&#xA;&#xA;&#x9;&#x9;return find(server.getCapabilities().getLayer(), name);&#xA;&#x9;}&#xA;&#xA;&#x9;private org.geotools.ows.wms.Layer find(&#xA;&#x9;&#x9;&#x9;org.geotools.ows.wms.Layer root,&#xA;&#x9;&#x9;&#x9;String name&#xA;&#x9;) {&#xA;&#x9;&#x9;if (name.equals(root.getName())) {&#xA;&#x9;&#x9;&#x9;return root;&#xA;&#x9;&#x9;}&#xA;&#xA;&#x9;&#x9;for (var c : root.getLayerChildren()) {&#xA;&#x9;&#x9;&#x9;org.geotools.ows.wms.Layer r = find(c, name);&#xA;&#x9;&#x9;&#x9;if (r != null) return r;&#xA;&#x9;&#x9;}&#xA;&#xA;&#x9;&#x9;return null;&#xA;&#x9;}&#xA;&#xA;    public BufferedImage getMap(&#xA;&#x9;&#x9;List&amp;lt;String&amp;gt; layers,&#xA;&#x9;&#x9;String bbox,&#xA;&#x9;&#x9;String crs,&#xA;&#x9;&#x9;int width,&#xA;&#x9;&#x9;int height&#xA;    ) throws Exception {&#xA;&#xA;        String url =&#xA;&#x9;&#x9;&#x9;wmsUrl +&#xA;&#x9;&#x9;&#x9;&amp;#34;?service=WMS&amp;#34; +&#xA;&#x9;&#x9;&#x9;&amp;#34;&amp;amp;request=GetMap&amp;#34; +&#xA;&#x9;&#x9;&#x9;&amp;#34;&amp;amp;version=1.1.1&amp;#34; +&#xA;&#x9;&#x9;&#x9;&amp;#34;&amp;amp;layers=&amp;#34; + String.join(&amp;#34;,&amp;#34;, layers) +&#xA;&#x9;&#x9;&#x9;&amp;#34;&amp;amp;bbox=&amp;#34; + bbox +&#xA;&#x9;&#x9;&#x9;&amp;#34;&amp;amp;width=&amp;#34; + width +&#xA;&#x9;&#x9;&#x9;&amp;#34;&amp;amp;height=&amp;#34; + height +&#xA;&#x9;&#x9;&#x9;&amp;#34;&amp;amp;srs=&amp;#34; + crs +&#xA;&#x9;&#x9;&#x9;&amp;#34;&amp;amp;format=image/png&amp;#34;;&#xA;&#x9;&#x9;&#xA;        return ImageIO.read(new URL(url));&#xA;    }&#xA;}&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;h3 class=wp-block-heading&gt;10.4. The &lt;code&gt;MapPanel&lt;/code&gt; Class&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;The &lt;code&gt;MapPanel&lt;/code&gt; class extends &lt;code&gt;JPanel&lt;/code&gt; and serves as a custom graphics canvas dedicated to drawing the fetched WMS map imagery (&lt;code&gt;BufferedImage&lt;/code&gt;) onto the client UI application framework.&lt;ul class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;Image State Invalidation and Repainting (&lt;code&gt;setImage&lt;/code&gt;)&lt;/strong&gt;:&lt;ul class=wp-block-list&gt;&lt;li&gt;This method acts as a standard state mutator. When called by the master controller, it caches the newly fetched geospatial bitmap into the local &lt;code&gt;image&lt;/code&gt; field.&lt;li&gt;It immediately invokes &lt;strong&gt;&lt;code&gt;repaint()&lt;/code&gt;&lt;/strong&gt;, which posts an asynchronous paint event to the Swing Event Dispatch Thread (EDT), prompting the framework to refresh the visible graphical region without lagging the main UI loop.&lt;/ul&gt;&lt;li&gt;&lt;strong&gt;Graphics Pipeline Lifecycle Hooks (&lt;code&gt;paintComponent&lt;/code&gt;)&lt;/strong&gt;:&lt;ul class=wp-block-list&gt;&lt;li&gt;The class overrides &lt;code&gt;paintComponent(Graphics g)&lt;/code&gt; to inject custom drawing logic directly into the native window composite layer.&lt;li&gt;&lt;strong&gt;&lt;code&gt;super.paintComponent(g)&lt;/code&gt;&lt;/strong&gt; is executed sequentially at the absolute beginning of the routine to properly clear the background buffer and purge the component canvas, eliminating potential artifact ghosts or visual rendering anomalies.&lt;/ul&gt;&lt;li&gt;&lt;strong&gt;Dynamic Viewport Boundary Scaling (&lt;code&gt;g.drawImage&lt;/code&gt;)&lt;/strong&gt;:&lt;ul class=wp-block-list&gt;&lt;li&gt;If a valid &lt;code&gt;BufferedImage&lt;/code&gt; frame resides in the pipeline memory, the rendering engine triggers &lt;code&gt;g.drawImage()&lt;/code&gt;.&lt;li&gt;It anchors the mapping source coordinates at the localized screen origin (0, 0). By supplying the dynamic runtime boundaries &lt;strong&gt;&lt;code&gt;getWidth()&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;getHeight()&lt;/code&gt;&lt;/strong&gt; into the layout matrix parameters, the client application ensures that the remote map grid stretches and conforms scaling matrices on the fly to perfectly snap fit into the container dimensions whenever window resizing triggers.&lt;/ul&gt;&lt;/ul&gt;&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: java; title: ; notranslate&#34;&gt;package com.honolulu.gis;&#xA;&#xA;import javax.swing.*;&#xA;import java.awt.*;&#xA;import java.awt.image.BufferedImage;&#xA;&#xA;public class MapPanel extends JPanel {&#xA;&#xA;    private BufferedImage image;&#xA;&#xA;    public void setImage(BufferedImage image) {&#xA;        this.image = image;&#xA;        repaint();&#xA;    }&#xA;&#xA;    @Override&#xA;    protected void paintComponent(&#xA;            Graphics g) {&#xA;&#xA;        super.paintComponent(g);&#xA;&#xA;        if (image != null) {&#xA;&#xA;            g.drawImage(&#xA;                    image,&#xA;                    0,&#xA;                    0,&#xA;                    getWidth(),&#xA;                    getHeight(),&#xA;                    null&#xA;            );&#xA;        }&#xA;    }&#xA;}&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;h3 class=wp-block-heading&gt;10.5. The &lt;code&gt;WmsLayerInfo&lt;/code&gt; Class&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;The &lt;code&gt;WmsLayerInfo&lt;/code&gt; component represents the lightweight data access model utilized to encapsulate the primary remote Web Map Service (WMS) layer specifications parsed from GeoServer.&lt;ul class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;Immutable Java Record Architecture&lt;/strong&gt;:&lt;ul class=wp-block-list&gt;&lt;li&gt;The class leverages the modern &lt;strong&gt;Java Record&lt;/strong&gt; configuration framework. This design pattern intrinsically eliminates traditional boilerplates such as boilerplate explicit Accessors (Getters), &lt;code&gt;equals()&lt;/code&gt;, &lt;code&gt;hashCode()&lt;/code&gt;, and &lt;code&gt;toString()&lt;/code&gt; generation blocks.&lt;li&gt;By default, records evaluate fields as implicitly &lt;code&gt;private final&lt;/code&gt;, enforcing complete object &lt;strong&gt;immutability&lt;/strong&gt; that ensures thread safety and component integrity throughout the data stream workflow.&lt;/ul&gt;&lt;li&gt;&lt;strong&gt;Metadata Fields Breakdown&lt;/strong&gt;:&lt;ul class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;&lt;code&gt;namespace&lt;/code&gt;&lt;/strong&gt;: Identifies the operational work domain workspace (e.g., &lt;code&gt;&amp;#34;Honolulu&amp;#34;&lt;/code&gt;), facilitating smooth upstream filter streams and grouping transformations inside the tree panel component.&lt;li&gt;&lt;strong&gt;&lt;code&gt;name&lt;/code&gt;&lt;/strong&gt;: Contains the raw, fully qualified canonical system identifier required by the remote GeoServer container to compile target map visuals within WMS URL parameters.&lt;li&gt;&lt;strong&gt;&lt;code&gt;title&lt;/code&gt;&lt;/strong&gt;: Represents the localized, human-readable display string used for populating label text within the user interface graphical component tree views.&lt;/ul&gt;&lt;/ul&gt;&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: plain; title: ; notranslate&#34;&gt;package com.honolulu.gis;&#xA;&#xA;public record WmsLayerInfo(&#xA;        String namespace,&#xA;        String name,&#xA;        String title&#xA;) {&#xA;}&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;h3 class=wp-block-heading&gt;10.6. Build and Execution&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;You can now proceed with building and running the application by executing the following commands in the currently open Windows Command Prompt (cmd) window.&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: plain; title: ; notranslate&#34;&gt;mvn clean package&#xA;mvn exec:java -Dexec.mainClass=com.honolulu.gis.Main&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;p class=wp-block-paragraph&gt;Once the application is running, you can use the developed WMS client to interactively view and inspect each geospatial dataset loaded into GeoServer, one layer at a time, as shown below.&lt;figure class=&#34;wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-8 is-layout-flex wp-block-gallery-is-layout-flex&#34;&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_1.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_1-1024x659.png decoding=async width=1024 height=659 data-id=143963 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_1-1024x659.png alt class=wp-image-143963 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_1-1024x659.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_1-300x193.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_1-768x494.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_1.png 1389w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=659 data-id=143963 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_1-1024x659.png alt class=wp-image-143963 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_1-1024x659.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_1-300x193.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_1-768x494.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_1.png 1389w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_2.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_2-1024x656.png decoding=async width=1024 height=656 data-id=143964 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_2-1024x656.png alt class=wp-image-143964 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_2-1024x656.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_2-300x192.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_2-768x492.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_2.png 1390w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=656 data-id=143964 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_2-1024x656.png alt class=wp-image-143964 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_2-1024x656.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_2-300x192.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_2-768x492.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_2.png 1390w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_3.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_3-1024x659.png decoding=async width=1024 height=659 data-id=143962 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_3-1024x659.png alt class=wp-image-143962 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_3-1024x659.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_3-300x193.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_3-768x494.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_3.png 1387w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=659 data-id=143962 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_3-1024x659.png alt class=wp-image-143962 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_3-1024x659.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_3-300x193.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_3-768x494.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_3.png 1387w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_4.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_4-1024x660.png decoding=async width=1024 height=660 data-id=143961 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_4-1024x660.png alt class=wp-image-143961 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_4-1024x660.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_4-300x193.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_4-768x495.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_4.png 1385w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=660 data-id=143961 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_4-1024x660.png alt class=wp-image-143961 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_4-1024x660.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_4-300x193.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_4-768x495.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_4.png 1385w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_5.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_5-1024x661.png decoding=async width=1024 height=661 data-id=143965 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_5-1024x661.png alt class=wp-image-143965 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_5-1024x661.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_5-300x194.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_5-768x496.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_5.png 1383w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=661 data-id=143965 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_5-1024x661.png alt class=wp-image-143965 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_5-1024x661.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_5-300x194.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_5-768x496.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/wms_service_5.png 1383w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/figure&gt;&lt;h2 class=wp-block-heading&gt;11. Conclusion&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;In this post, we have briefly introduced how to load geospatial data into a map server and how to consume that loaded data via a Web Map Service (WMS). To transition this into a fully-featured, production-ready map service, various additional capabilities and advanced functionalities would need to be incorporated.&lt;h2 class=wp-block-heading&gt;12. Download Links&lt;/h2&gt;&lt;ul class=wp-block-list&gt;&lt;li&gt;Open JDK : &lt;a href=https://jdk.java.net/java-se-ri/21 target=_blank rel=&#34;noreferrer noopener&#34;&gt;https://jdk.java.net/java-se-ri/21&lt;/a&gt;&lt;li&gt;Maven Project : &lt;a href=https://maven.apache.org/download.cgi target=_blank rel=&#34;noreferrer noopener&#34;&gt;https://maven.apache.org/download.cgi&lt;/a&gt;&lt;li&gt;GeoServer Project :&lt;ul class=wp-block-list&gt;&lt;li&gt;&lt;a href=https://geoserver.org/download/ target=_blank rel=&#34;noreferrer noopener&#34;&gt;https://geoserver.org/download/&lt;/a&gt;&lt;li&gt;&lt;a href=https://sourceforge.net/projects/geoserver/files/GeoServer/2.28.4/ target=_blank rel=&#34;noreferrer noopener&#34;&gt;https://sourceforge.net/projects/geoserver/files/GeoServer/2.28.4/&lt;/a&gt;&lt;/ul&gt;&lt;li&gt;Honolulu GIS Data : &lt;a href=https://honolulu-cchnl.opendata.arcgis.com target=_blank rel=&#34;noreferrer noopener&#34;&gt;https://honolulu-cchnl.opendata.arcgis.com&lt;/a&gt;&lt;/ul&gt;&lt;h2 class=wp-block-heading&gt;13. Trouble Shooting&lt;/h2&gt;&lt;ul class=wp-block-list&gt;&lt;li&gt;In an intranet environment, you may need to recompile your project using Maven with the following flags to bypass SSL verification:&lt;/ul&gt;&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: plain; title: ; notranslate&#34;&gt;mvn clean compile -Dmaven.wagon.http.ssl.insecure=true -Dmaven.wagon.http.ssl.allowall=true&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;ul class=wp-block-list&gt;&lt;li&gt;Alternatively, you can update the Java certificate chain. First, open the &lt;a href=https://repo.osgeo.org/ id=https://repo.osgeo.org/ target=_blank rel=&#34;noreferrer noopener&#34;&gt;osgeo&lt;/a&gt; website in your browser and download its certificate (&lt;code&gt;&lt;a href=https://www.servicenow.com/community/secops-blog/obtain-the-ssl-certificate-for-a-website-or-from-the-browser/ba-p/2282519 id=https://www.servicenow.com/community/secops-blog/obtain-the-ssl-certificate-for-a-website-or-from-the-browser/ba-p/2282519 target=_blank rel=&#34;noreferrer noopener&#34;&gt;nexus.osgeo.org.crt&lt;/a&gt;&lt;/code&gt;). Then, run the following command to import it into your keystore:&lt;/ul&gt;&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: plain; title: ; notranslate&#34;&gt;keytool -importcert -keystore &amp;#34;C:\DEV\Works\MapService\jdk-21\lib\security\cacerts&amp;#34; -storepass changeit -file &amp;#34;C:\DEV\Works\MapService\MapClient\nexus.osgeo.org.crt&amp;#34; -alias osgeo_repo&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;h2 class=wp-block-heading&gt;14. Download the source code&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;The source code for this post is available for download. Keep in mind that &lt;strong&gt;the Object Detector App requires specific models and resources to run properly.&lt;/strong&gt; You can download these essential model files and assets in &lt;strong&gt;Section 14: Resources&lt;/strong&gt; below.&lt;div class=download&gt;&lt;strong&gt;Download&lt;/strong&gt;&lt;br&gt;You can download the app source code of this post here:&lt;br&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/MapClient.zip&gt;&lt;strong&gt;Simple Java Gis Map Service Client&lt;/strong&gt;&lt;/a&gt;&lt;/div&gt;&lt;style&gt;.lepopup-progress-60 div.lepopup-progress-t1&gt;div{background-color:#e0e0e0;}.lepopup-progress-60 div.lepopup-progress-t1&gt;div&gt;div{background-color:#bd4070;}.lepopup-progress-60 div.lepopup-progress-t1&gt;div&gt;div{color:#ffffff;}.lepopup-progress-60 div.lepopup-progress-t1&gt;label{color:#444444;}.lepopup-form-60, .lepopup-form-60 *, .lepopup-progress-60 {font-size:15px;color:#444444;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-signature-box span i{font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#555555;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-signature-box,.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;text&#39;],.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;email&#39;],.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;password&#39;],.lepopup-form-60 .lepopup-element div.lepopup-input select,.lepopup-form-60 .lepopup-element div.lepopup-input select option,.lepopup-form-60 .lepopup-element div.lepopup-input textarea{font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#555555;font-style:normal;text-decoration:none;text-align:left;background-color:rgba(255, 255, 255, 0.7);background-image:none;border-width:1px;border-style:solid;border-color:#cccccc;border-radius:0px;box-shadow: inset 0px 0px 15px -7px #000000;}.lepopup-form-60 .lepopup-element div.lepopup-input ::placeholder{color:#555555; opacity: 0.9;} .lepopup-form-60 .lepopup-element div.lepopup-input ::-ms-input-placeholder{color:#555555; opacity: 0.9;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect::-webkit-scrollbar-thumb{background-color:#cccccc;}.lepopup-form-60 .lepopup-element div.lepopup-input&gt;i.lepopup-icon-left, .lepopup-form-60 .lepopup-element div.lepopup-input&gt;i.lepopup-icon-right{font-size:20px;color:#444444;border-radius:0px;}.lepopup-form-60 .lepopup-element .lepopup-button,.lepopup-form-60 .lepopup-element .lepopup-button:visited{font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#ffffff;font-weight:700;font-style:normal;text-decoration:none;text-align:center;background-color:#326693;background-image:none;border-width:1px;border-style:solid;border-color:#326693;border-radius:0px;box-shadow:none;}.lepopup-form-60 .lepopup-element div.lepopup-input .lepopup-imageselect+label{border-width:1px;border-style:solid;border-color:#cccccc;border-radius:0px;box-shadow:none;}.lepopup-form-60 .lepopup-element div.lepopup-input .lepopup-imageselect+label span.lepopup-imageselect-label{font-size:15px;color:#444444;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl:checked+label:after{background-color:rgba(255, 255, 255, 0.7);}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-classic+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-fa-check+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-square+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl+label{background-color:rgba(255, 255, 255, 0.7);border-color:#cccccc;color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-square:checked+label:after{background-color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl:checked+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl+label:after{background-color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-classic+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-fa-check+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-dot+label{background-color:rgba(255, 255, 255, 0.7);border-color:#cccccc;color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-dot:checked+label:after{background-color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect&gt;input[type=&#39;checkbox&#39;]+label:hover{background-color:#bd4070;color:#ffffff;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect&gt;input[type=&#39;checkbox&#39;]:checked+label{background-color:#a93a65;color:#ffffff;}.lepopup-form-60 .lepopup-element input[type=&#39;checkbox&#39;].lepopup-tile+label, .lepopup-form-60 .lepopup-element input[type=&#39;radio&#39;].lepopup-tile+label {font-size:15px;color:#444444;font-style:normal;text-decoration:none;text-align:center;background-color:#ffffff;background-image:none;border-width:1px;border-style:solid;border-color:#cccccc;border-radius:0px;box-shadow:none;}.lepopup-form-60 .lepopup-element-error{font-size:15px;color:#ffffff;font-style:normal;text-decoration:none;text-align:left;background-color:#d9534f;background-image:none;}.lepopup-form-60 .lepopup-element-2 {background-color:rgba(226, 236, 250, 1);background-image:none;border-width:1px;border-style:solid;border-color:rgba(216, 216, 216, 1);border-radius:3px;box-shadow: 1px 1px 15px -6px #d7e1eb;}.lepopup-form-60 .lepopup-element-3 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:26px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-3 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:26px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-3 .lepopup-element-html-content {min-height:73px;}.lepopup-form-60 .lepopup-element-4 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:19px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-4 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:19px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-4 .lepopup-element-html-content {min-height:23px;}.lepopup-form-60 .lepopup-element-5 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-5 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-5 .lepopup-element-html-content {min-height:24px;}.lepopup-form-60 .lepopup-element-6 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-6 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-6 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-7 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-7 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-7 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-8 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-8 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-8 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-9 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-9 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-9 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-10 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-10 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-10 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-11 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-11 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-11 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-12 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-12 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-12 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-13 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-13 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-13 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-14 div.lepopup-input .lepopup-icon-left, .lepopup-form-60 .lepopup-element-14 div.lepopup-input .lepopup-icon-right {line-height:36px;}.lepopup-form-60 .lepopup-element-15 div.lepopup-input{height:auto;line-height:1;}.lepopup-form-60 .lepopup-element-16 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:14px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-16 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:14px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-16 .lepopup-element-html-content {min-height:5px;}.lepopup-form-60 .lepopup-element-19 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#333333;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-19 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#333333;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-19 .lepopup-element-html-content {min-height:363px;}.lepopup-form-60 .lepopup-element-0 * {font-size:15px;color:#ffffff;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-0 {font-size:15px;color:#ffffff;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:#5cb85c;background-image:none;border-width:0px;border-style:solid;border-color:#ccc;border-radius:5px;box-shadow: 1px 1px 15px -6px #000000;padding-top:40px;padding-right:40px;padding-bottom:40px;padding-left:40px;}.lepopup-form-60 .lepopup-element-0 .lepopup-element-html-content {min-height:160px;}&lt;/style&gt;&lt;div class=lepopup-inline style=&#34;margin: 0 auto;&#34;&gt;&lt;div class=&#34;lepopup-form lepopup-form-60 lepopup-form-sCJ7cEs3idoUuE4D lepopup-form-icon-inside lepopup-form-position-middle-right&#34; data-session=0 data-id=sCJ7cEs3idoUuE4D data-form-id=60 data-slug=7lQM6oyWL5bTm5lw data-title=&#34;Under the Post Inline&#34; data-page=1 data-xd=off data-width=820 data-height=430 data-position=middle-right data-esc=off data-enter=on data-disable-scrollbar=off style=display:none;width:820px;height:430px; onclick=event.stopPropagation();&gt;&lt;div class=lepopup-form-inner style=width:820px;height:430px;&gt;&lt;div class=&#34;lepopup-element lepopup-element-2 lepopup-element-rectangle&#34; data-type=rectangle data-top=0 data-left=0 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:501;top:0px;left:0px;width:820px;height:430px;&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-3 lepopup-element-html&#34; data-type=html data-top=7 data-left=10 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:502;top:7px;left:10px;width:797px;height:73px;&gt;&lt;div class=lepopup-element-html-content&gt;Do you want to know how to develop your skillset to become a &lt;span style=&#34;color: #CAB43D; text-shadow: 1px 1px #835D5D;&#34;&gt;Java Rockstar?&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-4 lepopup-element-html&#34; data-type=html data-top=83 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:503;top:83px;left:308px;width:473px;height:23px;&gt;&lt;div class=lepopup-element-html-content&gt;Subscribe to our newsletter to start Rocking &lt;span style=&#34;text-decoration: underline;&#34;&gt;right now!&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-5 lepopup-element-html&#34; data-type=html data-top=107 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:504;top:107px;left:308px;width:473px;height:24px;&gt;&lt;div class=lepopup-element-html-content&gt;To get you started we give you our best selling eBooks for &lt;span style=&#34;color:#e01404; text-shadow: 1px 1px #C99924; font-size: 15px;&#34;&gt;FREE!&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-6 lepopup-element-html&#34; data-type=html data-top=136 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:505;top:136px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;1.&lt;/span&gt; JPA Mini Book&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-7 lepopup-element-html&#34; data-type=html data-top=156 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:506;top:156px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;2.&lt;/span&gt; JVM Troubleshooting Guide&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-8 lepopup-element-html&#34; data-type=html data-top=176 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:507;top:176px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;3.&lt;/span&gt; JUnit Tutorial for Unit Testing&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-9 lepopup-element-html&#34; data-type=html data-top=196 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:508;top:196px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;4.&lt;/span&gt; Java Annotations Tutorial&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-10 lepopup-element-html&#34; data-type=html data-top=216 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:509;top:216px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;5.&lt;/span&gt; Java Interview Questions&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-11 lepopup-element-html&#34; data-type=html data-top=236 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:510;top:236px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;6.&lt;/span&gt; Spring Interview Questions&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-12 lepopup-element-html&#34; data-type=html data-top=256 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:511;top:256px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;7.&lt;/span&gt; Android UI Design&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-13 lepopup-element-html&#34; data-type=html data-top=282 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:512;top:282px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;and many more ....&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-14&#34; data-type=email data-deps data-id=14 data-top=305 data-left=308 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:513;top:305px;left:308px;width:473px;height:36px;&gt;&lt;div class=lepopup-input&gt;&lt;input type=email name=lepopup-14 class=lepopup-ta-left placeholder=&#34;Enter your e-mail...&#34; autocomplete=email data-default aria-label=&#34;Email Field&#34; oninput=lepopup_input_changed(this); onfocus=lepopup_input_error_hide(this);&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-15&#34; data-type=checkbox data-deps data-id=15 data-top=344 data-left=308 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:514;top:344px;left:308px;width:160px;&gt;&lt;div class=&#34;lepopup-input lepopup-cr-layout-1 lepopup-cr-layout-left&#34;&gt;&lt;div class=&#34;lepopup-cr-container lepopup-cr-container-medium lepopup-cr-container-left&#34;&gt;&lt;div class=lepopup-cr-box&gt;&lt;input class=&#34;lepopup-checkbox lepopup-checkbox-classic lepopup-checkbox-medium&#34; type=checkbox name=lepopup-15[] id=lepopup-checkbox-DCLIhnH1BcJ7xNbL-14-0 value=on data-default=off onchange=lepopup_input_changed(this);&gt;&lt;label for=lepopup-checkbox-DCLIhnH1BcJ7xNbL-14-0 onclick=lepopup_input_error_hide(this);&gt;&lt;/label&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-cr-label lepopup-ta-left&#34;&gt;&lt;label for=lepopup-checkbox-DCLIhnH1BcJ7xNbL-14-0 onclick=lepopup_input_error_hide(this);&gt;&lt;/label&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-16 lepopup-element-html&#34; data-type=html data-top=344 data-left=338 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:515;top:344px;left:338px;width:350px;height:5px;&gt;&lt;div class=lepopup-element-html-content&gt;I agree to the &lt;a href=https://www.javacodegeeks.com/about/terms-of-use target=_blank&gt;Terms&lt;/a&gt; and &lt;a href=https://www.javacodegeeks.com/about/privacy-policy target=_blank&gt;Privacy Policy&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-17&#34; data-type=button data-top=372 data-left=308 data-animation-in=bounceIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:516;top:372px;left:308px;width:85px;height:37px;&gt;&lt;a class=&#34;lepopup-button lepopup-button-zoom-out&#34; href=https://www.javacodegeeks.com/feed/ onclick=&#34;return lepopup_submit(this);&#34; data-label=&#34;Sign up&#34; data-loading=Loading...&gt;&lt;span&gt;Sign up&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-19 lepopup-element-html&#34; data-type=html data-top=67 data-left=-15 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:518;top:67px;left:-15px;width:320px;height:363px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2015/01/books_promo.png decoding=async data-src=https://www.javacodegeeks.com/wp-content/uploads/2015/01/books_promo.png alt width=320 height=363&gt;&lt;noscript&gt;&lt;img decoding=async src=https://www.javacodegeeks.com/wp-content/uploads/2015/01/books_promo.png alt width=320 height=363&gt;&lt;/noscript&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-form lepopup-form-60 lepopup-form-sCJ7cEs3idoUuE4D lepopup-form-icon-inside lepopup-form-position-middle-right&#34; data-session=0 data-id=sCJ7cEs3idoUuE4D data-form-id=60 data-slug=7lQM6oyWL5bTm5lw data-title=&#34;Under the Post Inline&#34; data-page=confirmation data-xd=off data-width=420 data-height=320 data-position=middle-right data-esc=off data-enter=on data-disable-scrollbar=off style=display:none;width:420px;height:320px; onclick=event.stopPropagation();&gt;&lt;div class=lepopup-form-inner style=width:420px;height:320px;&gt;&lt;div class=&#34;lepopup-element lepopup-element-0 lepopup-element-html&#34; data-type=html data-top=80 data-left=70 data-animation-in=bounceInDown data-animation-out=fadeOutUp style=animation-duration:1000ms;animation-delay:0ms;z-index:500;top:80px;left:70px;width:280px;height:160px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;h4 style=&#34;text-align: center; font-size: 18px; font-weight: bold;&#34;&gt;Thank you!&lt;/h4&gt;&lt;p style=&#34;text-align: center;&#34;&gt;We will contact you soon.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;input type=hidden id=lepopup-logic-sCJ7cEs3idoUuE4D value=[]&gt;&lt;/div&gt;&lt;div class=&#34;post-bottom-meta post-bottom-tags post-tags-classic&#34;&gt;&lt;div class=post-bottom-meta-title&gt;&lt;span class=tie-icon-tags aria-hidden=true&gt;&lt;/span&gt;Tags&lt;/div&gt;&lt;span class=tagcloud&gt;&lt;a href=https://www.javacodegeeks.com/tag/geoserver rel=tag&gt;GeoServer&lt;/a&gt; &lt;a href=https://www.javacodegeeks.com/tag/gis rel=tag&gt;GIS&lt;/a&gt; &lt;a href=https://www.javacodegeeks.com/tag/wms-client rel=tag&gt;Wms Client&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div id=post-extra-info&gt;&lt;div class=theiaStickySidebar&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=clearfix&gt;&lt;/div&gt;</description>
      <author>young.gon</author>
      <guid>https://www.javacodegeeks.com/gis-map-service-introduction-in-java.html</guid>
      <pubDate>Wed, 24 Jun 2026 10:13:51 +0000</pubDate>
    </item>
    <item>
      <title>OpenCV Android Object Detector</title>
      <link>https://www.javacodegeeks.com/opencv-android-object-detector.html</link>
      <description>&lt;header class=entry-header-outer&gt;&lt;nav id=breadcrumb&gt;&lt;a href=https://www.javacodegeeks.com/&gt;&lt;span class=tie-icon-home aria-hidden=true&gt;&lt;/span&gt;Home&lt;/a&gt;&lt;em class=delimiter&gt;»&lt;/em&gt;&lt;a href=https://www.javacodegeeks.com/category/java&gt;Java&lt;/a&gt;&lt;em class=delimiter&gt;»&lt;/em&gt;&lt;span class=current&gt;OpenCV Android Object Detector&lt;/span&gt;&lt;/nav&gt;&lt;div class=entry-header&gt;&lt;span class=post-cat-wrap&gt;&lt;a class=&#34;post-cat tie-cat-10&#34; href=https://www.javacodegeeks.com/category/android&gt;Android&lt;/a&gt;&lt;a class=&#34;post-cat tie-cat-11&#34; href=https://www.javacodegeeks.com/category/android/android-core&gt;Android Core&lt;/a&gt;&lt;a class=&#34;post-cat tie-cat-7&#34; href=https://www.javacodegeeks.com/category/java/core-java&gt;Core Java&lt;/a&gt;&lt;a class=&#34;post-cat tie-cat-6&#34; href=https://www.javacodegeeks.com/category/java&gt;Java&lt;/a&gt;&lt;/span&gt;&lt;h1 class=&#34;post-title entry-title&#34;&gt;OpenCV Android Object Detector&lt;/h1&gt;&lt;/div&gt;&lt;/header&gt;&lt;div class=&#34;entry-content entry clearfix&#34;&gt;&lt;div class=&#34;stream-item stream-item-above-post-content&#34;&gt;&lt;div class=stream-item-size&gt;&lt;div id=adngin-in-post-0 style=&#34;float:left; margin-right:20px; margin-bottom:10px; width:300px; height:274px;&#34;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p class=wp-block-paragraph&gt;This post will be the final chapter of my series on object detection since we have explored the possibility of detecting various objects within camera frames, tracing the journey from Java-based applications to our ultimate goal that implements a mobile app on android devices.&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD.jpg&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD-1024x620.jpg fetchpriority=high decoding=async width=1024 height=620 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD-1024x620.jpg alt class=wp-image-143689 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD-1024x620.jpg 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD-300x182.jpg 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD-768x465.jpg 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD-1536x931.jpg 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD-2048x1241.jpg 2048w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img fetchpriority=high decoding=async width=1024 height=620 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD-1024x620.jpg alt class=wp-image-143689 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD-1024x620.jpg 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD-300x182.jpg 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD-768x465.jpg 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD-1536x931.jpg 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD-2048x1241.jpg 2048w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;div class=toc&gt;&lt;h3&gt;Table Of Contents&lt;/h3&gt;&lt;dl&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#introduction&gt;1. Introduction&lt;/a&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#objectives&gt;2. Objectives&lt;/a&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#android_setup&gt;3. Android Development Setup&lt;/a&gt;&lt;dd&gt;&lt;dl&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#tools_setup&gt;3.1. Development Tools Setup&lt;/a&gt;&lt;/dl&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#build_opencv_samples&gt;4. Build OpenCV Samples&lt;/a&gt;&lt;dd&gt;&lt;dl&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#opencv_sdk&gt;4.1. Extracting the OpenCV SDK&lt;/a&gt;&lt;/dl&gt;&lt;dd&gt;&lt;dl&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#opencv_configuration&gt;4.2. OpenCV Sample Configuration&lt;/a&gt;&lt;/dl&gt;&lt;dd&gt;&lt;dl&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#studio_configuration&gt;4.3. Android Studio Configuration&lt;/a&gt;&lt;/dl&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#inference_models&gt;5. OpenCV Inference Models&lt;/a&gt;&lt;dd&gt;&lt;dl&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#models_overview&gt;5.1. Object Inference Model Overview&lt;/a&gt;&lt;/dl&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#adnroid_overview&gt;6. Android Overview&lt;/a&gt;&lt;dd&gt;&lt;dl&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#lifecycle_stages&gt;6.1. Activity Lifecycle Stages&lt;/a&gt;&lt;/dl&gt;&lt;dd&gt;&lt;dl&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#android_manifest&gt;6.2. About AndroidManifest&lt;/a&gt;&lt;/dl&gt;&lt;dd&gt;&lt;dl&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#lifecycle_practice&gt;6.3. Activity Lifecycle in Practice&lt;/a&gt;&lt;/dl&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#helloworld_app&gt;7. Hello World App&lt;/a&gt;&lt;dd&gt;&lt;dl&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#helloworld_layout&gt;7.1. Hello World Layouts&lt;/a&gt;&lt;/dl&gt;&lt;dd&gt;&lt;dl&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#create_menu&gt;7.2. Creating Menu&lt;/a&gt;&lt;/dl&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#helloopencv_app&gt;8. Hello OpenCV App&lt;/a&gt;&lt;dd&gt;&lt;dl&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#components&gt;8.1. Components and Resources&lt;/a&gt;&lt;/dl&gt;&lt;dd&gt;&lt;dl&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#opencv_layout&gt;8.2. Hello OpenCV Layout&lt;/a&gt;&lt;/dl&gt;&lt;dd&gt;&lt;dl&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#main_class&gt;8.3. MyHelloOpenCVActivity&lt;/a&gt;&lt;/dl&gt;&lt;dd&gt;&lt;dl&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#results&gt;8.4. Results&lt;/a&gt;&lt;/dl&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#object_detector&gt;9. Object Detector App&lt;/a&gt;&lt;dd&gt;&lt;dl&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#camera_calibration&gt;9.1. Camera Calibration Overview&lt;/a&gt;&lt;/dl&gt;&lt;dd&gt;&lt;dl&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#my_object_detector&gt;9.2 My Object Detecor&lt;/a&gt;&lt;/dl&gt;&lt;dd&gt;&lt;dl&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#detection_process&gt;9.3. Object Detection Process&lt;/a&gt;&lt;/dl&gt;&lt;dd&gt;&lt;dl&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#role_detectornetdata&gt;9.4. The Role of DetectorNetData&lt;/a&gt;&lt;/dl&gt;&lt;dd&gt;&lt;dl&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#managing_model&gt;9.5. Managing Model Life Cycle&lt;/a&gt;&lt;/dl&gt;&lt;dd&gt;&lt;dl&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#dnnModelRepository&gt;9.6. DnnModelRepository&lt;/a&gt;&lt;/dl&gt;&lt;dd&gt;&lt;dl&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#interaction_flow&gt;9.7. Interaction Flow&lt;/a&gt;&lt;/dl&gt;&lt;dd&gt;&lt;dl&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#how_to_detect&gt;9.8. Object Detection Options&lt;/a&gt;&lt;/dl&gt;&lt;dd&gt;&lt;dl&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#object_detector_final&gt;9.9. Final Results of Object Detector&lt;/a&gt;&lt;/dl&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#summary&gt;10. Summary&lt;/a&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#references&gt;11. References&lt;/a&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#links&gt;12. Links&lt;/a&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#download_source&gt;13. Download the source code&lt;/a&gt;&lt;dt&gt;&lt;a href=https://www.javacodegeeks.com/feed/#download_howto&gt;14. How to Download Models and Resources&lt;/a&gt;&lt;/dl&gt;&lt;/div&gt;&lt;h2 class=wp-block-heading&gt;&lt;a name=introduction&gt;&lt;/a&gt;1. Introduction&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;You have some insight what an object detector looks like and explored various detection models and those usage So far, I will focus on object detection specifically on the real Android mobile device.&lt;br&gt;Then, we will discuss how to adapt our existing object detector with minimal changes—rather than starting from scratch on Android system. For more context, you may refer to my previous articles on References part.&lt;h2 class=wp-block-heading&gt;&lt;a name=objectives&gt;&lt;/a&gt;2. Objectives&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;My goal is to conduct a series of experiments to detect objects on mobile with various object detection models—such as Mask R-CNN, the YOLO series, and other state-of-the-art models—on actual mobile devices. When it comes to mobile development, we can consider the two major ecosystems: Android and iOS, I selected Android because it natively supports Java, our preferred language, allowing us to build a seamless environment..&lt;p class=wp-block-paragraph&gt;The ultimate objective is to implement a standalone object detector using OpenCV Android. When I first began this project, OpenCV samples did not include a mobile-ready object detector. However, recent versions of OpenCV now provide samples integrated with MobileNet. Therefore, I have decided to use these official samples as a baseline for comparison with other models.&lt;h2 class=wp-block-heading&gt;&lt;a name=android_setup&gt;&lt;/a&gt;3. Android Development Setup&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;Before implementation of the android app, you must first configure your Android development environment if you haven’t already. Developing an Android app means it is a procedure to building an executable for the Android OS, while Google provides the base OS, various manufacturers—such as Samsung, Xiaomi, and Vivo—adapt it for their devices with specific drivers for components like Bluetooth, Wi-Fi, and GPS. To build apps for this ecosystem, you can download the necessary SDK from the Google Developers site.&lt;p class=wp-block-paragraph&gt;There are several software languages available for Android development in which Kotlin is a popular choice, and its syntax is quite similar to Java, making it easy to learn for those with a Java background. (In my view, Kotlin’s rise was partly influenced by the long-standing legal disputes between Google and Oracle). While C/C++ and Python are also options, they can be more challenging to implement than Java or Kotlin. As emphasized throughout this series, I will be using Android Java. Not only is it my preferred language, but sticking with pure Java ensures consistency across all the articles we have covered so far.&lt;h3 class=wp-block-heading&gt;&lt;a name=tools_setup&gt;&lt;/a&gt;3.1. Development Tools Setup&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;In this section, I will introduce the essential development tools and SDK required to build and run our object detection application on Android.&lt;h4 class=wp-block-heading&gt;1. JDK (Java Development Kit)&lt;/h4&gt;&lt;figure class=&#34;wp-block-image size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.png decoding=async width=773 height=718 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.png alt class=wp-image-141910 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.png 773w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/1-300x279.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/1-768x713.png 768w&#34; data-sizes=&#34;(max-width: 773px) 100vw, 773px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=773 height=718 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.png alt class=wp-image-141910 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.png 773w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/1-300x279.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/1-768x713.png 768w&#34; sizes=&#34;(max-width: 773px) 100vw, 773px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;p class=wp-block-paragraph&gt;&lt;strong&gt;&lt;a href=https://jdk.java.net/17/ id=https://jdk.java.net/17/ target=_blank rel=&#34;noreferrer noopener&#34;&gt;Java Development Kit (JDK)&lt;/a&gt;&lt;/strong&gt; is an essential tool as the foundation of Android Java and it is impossible to develop Android applications without it, so downloading and installing the JDK should be your first priority. Although Google now promotes Kotlin as the primary development language but Java still remains a fundamental pillar of the Android ecosystem.&lt;p class=wp-block-paragraph&gt;For this project, I recommend using OpenJDK. You can download the compressed binaries from the official OpenJDK site. I will be using JDK 17 or higher to ensure compatibility with the latest Android build tools and libraries.&lt;h4 class=wp-block-heading&gt;2. Android Studio&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;&lt;a href=&#34;https://developer.android.com/studio?hl=en&#34; id=&#34;https://developer.android.com/studio?hl=en&#34; target=_blank rel=&#34;noreferrer noopener&#34;&gt;Android Studio&lt;/a&gt; is the free, standard IDE from Google, offering an intuitive and user-friendly GUI. While Eclipse was the primary tool when I first started, Android Studio has now become the undisputed mainstream choice for developers worldwide, providing a much more robust environment for building modern apps.&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/2-1.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/2-1-1024x770.png decoding=async width=1024 height=770 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/2-1-1024x770.png alt class=wp-image-141912 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/2-1-1024x770.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/2-1-300x225.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/2-1-768x577.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/2-1.png 1216w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=770 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/2-1-1024x770.png alt class=wp-image-141912 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/2-1-1024x770.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/2-1-300x225.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/2-1-768x577.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/2-1.png 1216w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;p class=wp-block-paragraph&gt;Another major benefit of developing with Android Studio is its seamless integration with the Android SDK. It bundles essential components, such as platform tools and build tools, directly within the IDE. This integrated approach allows us to save significant time and effort when setting up the development environment, letting us focus more on building the app itself.&lt;h4 class=wp-block-heading&gt;3. Gradle&lt;/h4&gt;&lt;figure class=&#34;wp-block-image size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/3.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/3.png decoding=async width=773 height=677 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/3.png alt class=wp-image-141913 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/3.png 773w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/3-300x263.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/3-768x673.png 768w&#34; data-sizes=&#34;(max-width: 773px) 100vw, 773px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=773 height=677 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/3.png alt class=wp-image-141913 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/3.png 773w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/3-300x263.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/3-768x673.png 768w&#34; sizes=&#34;(max-width: 773px) 100vw, 773px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;p class=wp-block-paragraph&gt;Building an Android application is a complex process that culminates in the creation of an &lt;strong&gt;APK (Android Package)&lt;/strong&gt; file. This requires a robust build tool to manage everything from code compilation to final integration. While there are three major build tools available—&lt;strong&gt;Ant, Maven, and Gradle&lt;/strong&gt;—I prefer using &lt;strong&gt;&lt;a href=https://gradle.org/releases/ id=https://gradle.org/releases/ target=_blank rel=&#34;noreferrer noopener&#34;&gt;Gradle&lt;/a&gt;&lt;/strong&gt;. It is the modern standard for Android development, offering the flexibility and power needed to streamline the entire build pipeline.&lt;p class=wp-block-paragraph&gt;&lt;strong&gt;The Build Process with Gradle&lt;/strong&gt;&lt;br&gt;By choosing Gradle as our build tool, we can efficiently manage the complex process of creating an Android app. The typical workflow consists of the following key stages:&lt;ul class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;Code Compilation:&lt;/strong&gt; Converting Java or Kotlin source code into bytecode.&lt;li&gt;&lt;strong&gt;Resource Integration: &lt;/strong&gt;Compiling and packaging app resources, such as images and XML layout files.&lt;li&gt;&lt;strong&gt;Dependency Management:&lt;/strong&gt; Linking external libraries and frameworks (like OpenCV) as required.&lt;li&gt;&lt;strong&gt;Code Optimization &amp;amp; Obfuscation: &lt;/strong&gt;Improving app performance and protecting the source code using tools like R8 or ProGuard.&lt;li&gt;&lt;strong&gt;Signing &amp;amp; Archiving: &lt;/strong&gt;Digitally signing the application for security and packaging it into the final APK (or AAB) file for distribution.&lt;/ul&gt;&lt;p class=wp-block-paragraph&gt;&lt;strong&gt;Why We Use Gradle&lt;/strong&gt;&lt;br&gt;As developers, it is technically possible to perform each of these complex steps manually. However, doing so is far more complicated and error-prone than using a dedicated build tool. Utilizing a standardized build process through a tool like Gradle is not just natural—it is essential for efficiency and consistency. For this project, we will be using Gradle version 8.9, the latest stable release at this time.&lt;h4 class=wp-block-heading&gt;4. OpenCV Android SDK&lt;/h4&gt;&lt;figure class=&#34;wp-block-image size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.png decoding=async width=773 height=764 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.png alt class=wp-image-141914 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.png 773w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/5-300x297.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/5-768x759.png 768w&#34; data-sizes=&#34;(max-width: 773px) 100vw, 773px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=773 height=764 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.png alt class=wp-image-141914 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.png 773w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/5-300x297.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/5-768x759.png 768w&#34; sizes=&#34;(max-width: 773px) 100vw, 773px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;p class=wp-block-paragraph&gt;We are building our object detector on the OpenCV library. The &lt;strong&gt;&lt;a href=https://github.com/opencv/opencv/releases id=https://github.com/opencv/opencv/releases&gt;OpenCV Android SDK&lt;/a&gt;&lt;/strong&gt; offers not only the core libraries but also various practical samples to jump-start your development. &lt;strong&gt;Ensure you download&lt;/strong&gt; the latest version to take full advantage of current features and optimizations.&lt;h4 class=wp-block-heading&gt;5. About Android Mobile Device&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;While you can use the emulator provided by the Android SDK (which can be downloaded and configured via Android Studio), I believe it is not sufficient for this project so I have decided to use a physical device for optimal performance and testing —specifically, a &lt;strong&gt;Galaxy Tab S8&lt;/strong&gt;. Or It is possible to use your own Android phone or any other tablet for development.&lt;p class=wp-block-paragraph&gt;Specifications of Galaxy Tab S8 (Reference Device):&lt;figure class=wp-block-table&gt;&lt;table class=has-fixed-layout&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=has-text-align-left data-align=left&gt;Category&lt;td&gt;Specification&lt;tr&gt;&lt;td class=has-text-align-left data-align=left&gt;Model&lt;td&gt;Samsung Galaxy Tab S8 (Standard)&lt;tr&gt;&lt;td class=has-text-align-left data-align=left&gt;OS&lt;td&gt;Android 12 (Upgradable to 14+)&lt;tr&gt;&lt;td class=has-text-align-left data-align=left&gt;Processor (AP)&lt;td&gt;Qualcomm Snapdragon 8 Gen 1&lt;tr&gt;&lt;td class=has-text-align-left data-align=left&gt;Memory (RAM)&lt;td&gt;8 GB / 12 GB&lt;tr&gt;&lt;td class=has-text-align-left data-align=left&gt;Storage&lt;td&gt;128 GB / 256 GB (microSD up to 1TB)&lt;tr&gt;&lt;td class=has-text-align-left data-align=left&gt;Display&lt;td&gt;11-inch LTPS TFT (2560 x 1600), 120Hz&lt;tr&gt;&lt;td class=has-text-align-left data-align=left&gt;GPU&lt;td&gt;Adreno 730&lt;tr&gt;&lt;td class=has-text-align-left data-align=left&gt;NPU&lt;td&gt;7th Gen Qualcomm AI Engine&lt;/table&gt;&lt;/figure&gt;&lt;p class=wp-block-paragraph&gt;Please note that I assume your device is relatively modern. It is practically impossible to build an app that runs flawlessly on every version of Android ever released by providing the table below lists the specifications of my tablet. These are not necessarily the minimum requirements, but rather a reference for a high-performance setup. You should be able to follow the development process as long as your device is not outdated.&lt;a name=build_opencv_samples&gt;&lt;/a&gt;&lt;h2 class=wp-block-heading&gt;&lt;a name=build_opencv_samples&gt;&lt;/a&gt;4. Build OpenCV Samples&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;This section, I will describe how to build OpenCV samples since you’ve downloaded all tools and SDK completely from previous section.&lt;h3 class=wp-block-heading&gt;&lt;a name=opencv_sdk&gt;&lt;/a&gt;4.1. Extracting the OpenCV SDK&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;After downloading &lt;code&gt;opencv-version-android-sdk.zip&lt;/code&gt;, extract its contents to a folder of your choice. Once extracted, you will see a directory structure similar to the one shown below:&lt;figure class=&#34;wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex&#34;&gt;&lt;figure class=&#34;wp-block-image size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.png decoding=async width=765 height=333 data-id=141916 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.png alt class=wp-image-141916 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.png 765w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/7-300x131.png 300w&#34; data-sizes=&#34;(max-width: 765px) 100vw, 765px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=765 height=333 data-id=141916 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.png alt class=wp-image-141916 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.png 765w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/7-300x131.png 300w&#34; sizes=&#34;(max-width: 765px) 100vw, 765px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/figure&gt;&lt;ul class=wp-block-list&gt;&lt;li&gt;&lt;code&gt;sdk&lt;/code&gt;: It contains the Android library projects, Java helper classes, and native JNI libraries (.so files) required for your app.&lt;li&gt;&lt;code&gt;samples&lt;/code&gt;: This directory provides various sample applications that demonstrate OpenCV’s capabilities, such as camera handling, image manipulation, and—most importantly for us—object detection.&lt;/ul&gt;&lt;figure class=&#34;wp-block-image size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/05/opencv-sdk-dirs.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/opencv-sdk-dirs.png decoding=async width=866 height=358 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/opencv-sdk-dirs.png alt class=wp-image-143250 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/opencv-sdk-dirs.png 866w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/opencv-sdk-dirs-300x124.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/opencv-sdk-dirs-768x317.png 768w&#34; data-sizes=&#34;(max-width: 866px) 100vw, 866px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=866 height=358 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/opencv-sdk-dirs.png alt class=wp-image-143250 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/opencv-sdk-dirs.png 866w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/opencv-sdk-dirs-300x124.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/opencv-sdk-dirs-768x317.png 768w&#34; sizes=&#34;(max-width: 866px) 100vw, 866px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;p class=wp-block-paragraph&gt;The included samples are excellent resources for understanding how OpenCV code integrates and functions within the Android environment. By exploring these examples, you can gain practical insights into implementing computer vision features in a mobile context.&lt;h3 class=wp-block-heading&gt;&lt;a name=opencv_configuration&gt;&lt;/a&gt;4.2. OpenCV Sample Configuration&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;Now that we have downloaded the OpenCV SDK and explored its contents, we are ready to begin Android mobile development. Before diving into our custom implementation, let’s look at how to build and run the provided samples using &lt;strong&gt;Android Studio&lt;/strong&gt;. Testing these official examples ensures that your environment is correctly configured and gives you a functional baseline to work from.&lt;h4 class=wp-block-heading&gt;1. Launching Android Studio&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;If you have followed the setup steps described above, you can now launch the IDE. Navigate to the installation directory and locate the 64-bit executable file, &lt;code&gt;studio64.exe&lt;/code&gt; or studio.bat in the &lt;code&gt;bin&lt;/code&gt; folder.&lt;p class=wp-block-paragraph&gt;For example, based on our setup, the path should look like this:&lt;blockquote class=&#34;wp-block-quote is-layout-flow wp-block-quote-is-layout-flow&#34;&gt;&lt;p class=wp-block-paragraph&gt;~\android-studio\bin\studio64.exe&lt;br&gt;~\android-studio\bin\studio.bat&lt;/blockquote&gt;&lt;p class=wp-block-paragraph&gt;Double-click this file to start Android Studio and begin the project configuration.&lt;h4 class=wp-block-heading&gt;2. SDK Components Setup&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;When you launch Android Studio for the first time, you will encounter a window titled &lt;strong&gt;“SDK Components Setup.”&lt;/strong&gt; Fortunately, Android Studio automates the entire process—handling the download, configuration, and setup of the SDK and its components for us, as shown in the following screenshots:&lt;figure class=&#34;wp-block-image size-full is-resized&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/8.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/8.png decoding=async width=773 height=583 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/8.png alt class=wp-image-141917 style=aspect-ratio:1.3259092492830533;width:809px;height:auto data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/8.png 773w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/8-300x226.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/8-768x579.png 768w&#34; data-sizes=&#34;(max-width: 773px) 100vw, 773px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=773 height=583 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/8.png alt class=wp-image-141917 style=aspect-ratio:1.3259092492830533;width:809px;height:auto srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/8.png 773w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/8-300x226.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/8-768x579.png 768w&#34; sizes=&#34;(max-width: 773px) 100vw, 773px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;h4 class=wp-block-heading&gt;3. Development Toolchain&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;We call the process of building software for a different architecture or OS &lt;strong&gt;‘cross-compilation.’&lt;/strong&gt; Since Android relies on the Linux kernel, its applications inherently run within a Linux-based environment. To bridge the gap between our Windows development machines and the Android environment, we utilize a &lt;strong&gt;‘Toolchain’.&lt;/strong&gt;&lt;figure class=&#34;wp-block-image size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/9.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/9.png decoding=async width=773 height=584 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/9.png alt class=wp-image-141918 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/9.png 773w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/9-300x227.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/9-768x580.png 768w&#34; data-sizes=&#34;(max-width: 773px) 100vw, 773px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=773 height=584 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/9.png alt class=wp-image-141918 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/9.png 773w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/9-300x227.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/9-768x580.png 768w&#34; sizes=&#34;(max-width: 773px) 100vw, 773px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;h4 class=wp-block-heading&gt;4. OpenCV Sample Folder&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;Once the setup process described in the previous chapter is complete, the project selection window will appear then, In the window shown below, navigate to and select the &lt;code&gt;samples&lt;/code&gt; folder within the extracted OpenCV SDK :&lt;figure class=&#34;wp-block-image size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/10.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/10.png decoding=async width=773 height=556 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/10.png alt class=wp-image-141919 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/10.png 773w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/10-300x216.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/10-768x552.png 768w&#34; data-sizes=&#34;(max-width: 773px) 100vw, 773px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=773 height=556 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/10.png alt class=wp-image-141919 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/10.png 773w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/10-300x216.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/10-768x552.png 768w&#34; sizes=&#34;(max-width: 773px) 100vw, 773px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;h3 class=wp-block-heading&gt;&lt;a name=studio_configuration&gt;&lt;/a&gt;4.3. Android Studio Configuration&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;Set the &lt;strong&gt;JDK&lt;/strong&gt; and &lt;strong&gt;Gradle&lt;/strong&gt; versions we downloaded in the previous sections is first thing to do, before building. Setting these manually ensures that our build environment is consistent and stable.&lt;p class=wp-block-paragraph&gt;Follow these steps to complete the configuration:&lt;ol class=wp-block-list&gt;&lt;li&gt;Crucially, verify that the &lt;strong&gt;Gradle JDK&lt;/strong&gt; is set to &lt;strong&gt;version 17&lt;/strong&gt;. This ensures compatibility between the build tool and your Java source code.&lt;li&gt;Navigate to: &lt;strong&gt;Settings &amp;gt; Build, Execution, Deployment &amp;gt; Build Tools &amp;gt; Gradle&lt;/strong&gt;&lt;li&gt;In the &lt;strong&gt;“Build process”&lt;/strong&gt; or &lt;strong&gt;“Gradle projects”&lt;/strong&gt; section, look for the Gradle distribution options.&lt;li&gt;Choose &lt;strong&gt;“Specified location”&lt;/strong&gt; (or local installation) from the drop-down menu and enter the path where you extracted the Gradle 8.9 binaries.&lt;/ol&gt;&lt;figure class=&#34;wp-block-image size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/11.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/11.png decoding=async width=773 height=578 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/11.png alt class=wp-image-141920 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/11.png 773w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/11-300x224.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/11-768x574.png 768w&#34; data-sizes=&#34;(max-width: 773px) 100vw, 773px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=773 height=578 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/11.png alt class=wp-image-141920 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/11.png 773w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/11-300x224.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/11-768x574.png 768w&#34; sizes=&#34;(max-width: 773px) 100vw, 773px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;h4 class=wp-block-heading&gt;1. Exploring Sample Projects&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;With the configuration complete, you will now see a wide array of samples and examples —from basic camera preview to complex image processing filters — populated within the Android Studio project explorer that tells us these projects now “active,” meaning the IDE has recognized the Gradle files and linked the necessary OpenCV libraries.&lt;figure class=&#34;wp-block-image size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/12.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/12.png decoding=async width=773 height=599 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/12.png alt class=wp-image-141921 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/12.png 773w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/12-300x232.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/12-768x595.png 768w&#34; data-sizes=&#34;(max-width: 773px) 100vw, 773px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=773 height=599 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/12.png alt class=wp-image-141921 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/12.png 773w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/12-300x232.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/12-768x595.png 768w&#34; sizes=&#34;(max-width: 773px) 100vw, 773px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;p class=wp-block-paragraph&gt;On the official OpenCV site, there are available samples with description in which you can use these as a valuable reference throughout the development process:&lt;figure class=&#34;wp-block-image size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.png decoding=async width=773 height=713 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.png alt class=wp-image-141915 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.png 773w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/6-300x277.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/6-768x708.png 768w&#34; data-sizes=&#34;(max-width: 773px) 100vw, 773px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=773 height=713 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.png alt class=wp-image-141915 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.png 773w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/6-300x277.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/6-768x708.png 768w&#34; sizes=&#34;(max-width: 773px) 100vw, 773px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;h4 class=wp-block-heading&gt;2. Running Samples&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;You can build all these sample sources at a time by build, compile all sources at the menu of the android studio then, you simply select and run each of those samples with run button on the studio.&lt;figure class=&#34;wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-2 is-layout-flex wp-block-gallery-is-layout-flex&#34;&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/05/cap2.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/cap2-1024x554.png decoding=async width=1024 height=554 data-id=143621 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/cap2-1024x554.png alt class=wp-image-143621 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/cap2-1024x554.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/cap2-300x162.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/cap2-768x416.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/cap2-1536x831.png 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/cap2.png 1859w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=554 data-id=143621 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/cap2-1024x554.png alt class=wp-image-143621 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/cap2-1024x554.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/cap2-300x162.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/cap2-768x416.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/cap2-1536x831.png 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/cap2.png 1859w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/05/cap3.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/cap3-1024x520.png decoding=async width=1024 height=520 data-id=143622 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/cap3-1024x520.png alt class=wp-image-143622 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/cap3-1024x520.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/cap3-300x152.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/cap3-768x390.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/cap3.png 1376w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=520 data-id=143622 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/cap3-1024x520.png alt class=wp-image-143622 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/cap3-1024x520.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/cap3-300x152.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/cap3-768x390.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/cap3.png 1376w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/figure&gt;&lt;p class=wp-block-paragraph&gt;Those samples cover a wide range of functionalities, from basic camera access to advanced image processing techniques. Referring to them will help you understand the standard patterns for handling frame data and optimizing performance on mobile devices.&lt;figure class=&#34;wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-3 is-layout-flex wp-block-gallery-is-layout-flex&#34;&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/05/colorpicker-1.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/colorpicker-1-1024x584.png decoding=async width=1024 height=584 data-id=143259 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/colorpicker-1-1024x584.png alt class=wp-image-143259 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/colorpicker-1-1024x584.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/colorpicker-1-300x171.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/colorpicker-1-768x438.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/colorpicker-1.png 1224w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=584 data-id=143259 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/colorpicker-1-1024x584.png alt class=wp-image-143259 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/colorpicker-1-1024x584.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/colorpicker-1-300x171.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/colorpicker-1-768x438.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/colorpicker-1.png 1224w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/05/OCV-T2-mixed-processing.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/OCV-T2-mixed-processing-1024x721.png decoding=async width=1024 height=721 data-id=143257 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/OCV-T2-mixed-processing-1024x721.png alt class=wp-image-143257 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/OCV-T2-mixed-processing-1024x721.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/OCV-T2-mixed-processing-300x211.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/OCV-T2-mixed-processing-768x540.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/OCV-T2-mixed-processing.png 1215w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=721 data-id=143257 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/OCV-T2-mixed-processing-1024x721.png alt class=wp-image-143257 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/OCV-T2-mixed-processing-1024x721.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/OCV-T2-mixed-processing-300x211.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/OCV-T2-mixed-processing-768x540.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/OCV-T2-mixed-processing.png 1215w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/05/OCV-T3-Camera-Control-1.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/OCV-T3-Camera-Control-1-1024x643.png decoding=async width=1024 height=643 data-id=143255 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/OCV-T3-Camera-Control-1-1024x643.png alt class=wp-image-143255 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/OCV-T3-Camera-Control-1-1024x643.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/OCV-T3-Camera-Control-1-300x188.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/OCV-T3-Camera-Control-1-768x482.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/OCV-T3-Camera-Control-1.png 1208w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=643 data-id=143255 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/OCV-T3-Camera-Control-1-1024x643.png alt class=wp-image-143255 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/OCV-T3-Camera-Control-1-1024x643.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/OCV-T3-Camera-Control-1-300x188.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/OCV-T3-Camera-Control-1-768x482.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/OCV-T3-Camera-Control-1.png 1208w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/05/ocv_image_manupulation.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/ocv_image_manupulation-1024x690.png decoding=async width=1024 height=690 data-id=143256 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/ocv_image_manupulation-1024x690.png alt class=wp-image-143256 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/ocv_image_manupulation-1024x690.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/ocv_image_manupulation-300x202.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/ocv_image_manupulation-768x517.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/ocv_image_manupulation.png 1222w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=690 data-id=143256 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/ocv_image_manupulation-1024x690.png alt class=wp-image-143256 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/ocv_image_manupulation-1024x690.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/ocv_image_manupulation-300x202.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/ocv_image_manupulation-768x517.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/ocv_image_manupulation.png 1222w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/05/OCV15puzzle-1.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/OCV15puzzle-1-1024x773.png decoding=async width=1024 height=773 data-id=143258 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/OCV15puzzle-1-1024x773.png alt class=wp-image-143258 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/OCV15puzzle-1-1024x773.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/OCV15puzzle-1-300x226.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/OCV15puzzle-1-768x580.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/OCV15puzzle-1.png 1212w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=773 data-id=143258 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/OCV15puzzle-1-1024x773.png alt class=wp-image-143258 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/OCV15puzzle-1-1024x773.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/OCV15puzzle-1-300x226.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/OCV15puzzle-1-768x580.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/OCV15puzzle-1.png 1212w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/figure&gt;&lt;h2 class=wp-block-heading&gt;&lt;a name=inference_models&gt;&lt;/a&gt;5. OpenCV Inference Models&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;Basically, Mask-RCNN or Yolo v3 model we’ve been developing through the windows system is not suitable choice on the android system so I have to investigate some proper models on mobile system because I intent to build such circumstance that figure differences among the current models used so far and proper models as an aspect of accuracy or performance.&lt;h3 class=wp-block-heading&gt;&lt;a name=models_overview&gt;&lt;/a&gt;5.1. Object Inference Model Overview&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;We newly choose MobileNet-SSD v3, Yolo v3 tiny and Yolo v7 tiny as a mobile model downloaded from internet without any modification or training it following table is description of each models :&lt;figure class=wp-block-table&gt;&lt;table class=has-fixed-layout&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Model Name&lt;td&gt;Description&lt;td&gt;Focus Area&lt;tr&gt;&lt;td&gt;Mask R-CNN / YOLOv3&lt;td&gt;High accuracy models used in our Windows environment.&lt;td&gt;Accuracy &amp;amp; Precision&lt;tr&gt;&lt;td&gt;MobileNet-SSD v3&lt;td&gt;Google’s efficient CNN architecture designed for mobile vision.&lt;td&gt;Efficiency &amp;amp; Low Power&lt;tr&gt;&lt;td&gt;YOLOv3-tiny&lt;td&gt;A simplified, faster version of YOLOv3 with fewer layers.&lt;td&gt;Speed &amp;amp; Latency&lt;tr&gt;&lt;td&gt;YOLOv7-tiny&lt;td&gt;An optimized version of the YOLOv7 series for edge devices.&lt;td&gt;Balanced Speed/Accuracy&lt;/table&gt;&lt;/figure&gt;&lt;h4 class=wp-block-heading&gt;1. Model Download&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;I am certain that you already have the &lt;strong&gt;Mask R-CNN&lt;/strong&gt; and &lt;strong&gt;YOLOv3&lt;/strong&gt; models from the previous article. The table below lists the filenames and details for the remaining models. You can find these by searching the internet.&lt;p class=wp-block-paragraph&gt;For the experimental purposes of this article, you are also free to download any related model files or use your own custom-trained models instead.&lt;figure class=wp-block-table&gt;&lt;table class=has-fixed-layout&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;File Name&lt;td&gt;Location&lt;tr&gt;&lt;td&gt;frozen_inference_graph_ssd.pb&lt;br&gt;ssd_mobilenet_v3_large_coco_2020_01_14.pbtxt&lt;td&gt;1. github.com/opencv/opencv/wiki/tensorflow-object-detection-api&lt;tr&gt;&lt;td&gt;yolov3-tiny.weights&lt;td&gt;1. github.com/pjreddie/darknet/issues/2483&lt;br&gt;2. pjreddie.com/media/files/yolov3-tiny.weights&lt;tr&gt;&lt;td&gt;yolov7-tiny.weights&lt;td&gt;1.github.com/WongKinYiu/yolov7/releases/tag/v0.1&lt;/table&gt;&lt;/figure&gt;&lt;h4 class=wp-block-heading&gt;2. Inference Parameters&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;The OpenCV library provides the &lt;code&gt;blobFromImage()&lt;/code&gt; method, which is essential for preprocessing images or video frames into “blobs” that our object detection app can process. To ensure accurate results, this method requires specific inference parameters—such as scale factor, size, and mean subtraction—which vary significantly depending on the architecture of the model being used.&lt;p class=wp-block-paragraph&gt;The following table details the specific configurations for the &lt;code&gt;blobFromImage()&lt;/code&gt; method when using &lt;strong&gt;MobileNet-SSD&lt;/strong&gt;, &lt;strong&gt;YOLO&lt;/strong&gt;, and &lt;strong&gt;Mask R-CNN&lt;/strong&gt; models:&lt;figure class=wp-block-table&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Model Name&lt;td&gt;Size&lt;td&gt;Scale Factor&lt;td&gt;Mean Value&lt;tr&gt;&lt;td&gt;MobileNet-SSD&lt;td&gt;(512, 512)&lt;td&gt;1.0 / 127.5&lt;td&gt;Scalar(127.5, 127.5, 127.5)&lt;tr&gt;&lt;td&gt;YOLO v3 / v7 Tiny&lt;td&gt;(416, 416)&lt;td&gt;1.0 / 255.0&lt;td&gt;Scalar(0, 0, 0)&lt;tr&gt;&lt;td&gt;Mask R-CNN&lt;td&gt;(800, 800)&lt;td&gt;1.0&lt;td&gt;Scalar(0, 0, 0)&lt;/table&gt;&lt;/figure&gt;&lt;h4 class=wp-block-heading&gt;3. Performance Uncertainty&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;At this stage, I am not entirely certain whether the heavier models, like &lt;strong&gt;Mask R-CNN&lt;/strong&gt; and &lt;strong&gt;YOLOv3&lt;/strong&gt;, will function properly on a mobile device. Similarly, the actual performance of the more lightweight options, such as &lt;strong&gt;MobileNet-SSD&lt;/strong&gt; and the &lt;strong&gt;Tiny YOLO&lt;/strong&gt; variants, remains to be seen in a real-world Android environment.&lt;p class=wp-block-paragraph&gt;This uncertainty is exactly why we are conducting these tests—to determine which models are truly viable for mobile object detection.&lt;h2 class=wp-block-heading&gt;&lt;a name=adnroid_overview&gt;&lt;/a&gt;6. Android Overview&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;The &lt;strong&gt;Activity&lt;/strong&gt; class is the fundamental component used to develop an Android application before we proceed, it is essential to understand some basic Android GUI concepts. Every Android app operates by inheriting from a child class of the Activity class.&lt;p class=wp-block-paragraph&gt;This class follows &lt;strong&gt;six main lifecycle stages&lt;/strong&gt;, which define how the GUI components are internally created, initialized, and eventually destroyed.&lt;p class=wp-block-paragraph&gt;For example, rotating your device from landscape to portrait mode changes the screen orientation naturally, but &lt;strong&gt;it triggers the Android system to destroy and recreate the activity&lt;/strong&gt; behind the scenes.&lt;p class=wp-block-paragraph&gt;This means &lt;strong&gt;Android completely shuts down&lt;/strong&gt; the current instance of your activity and &lt;strong&gt;starts a fresh one&lt;/strong&gt; to accommodate the new screen dimensions. Understanding this behavior is crucial because it dictates how we manage data and resources—such as our camera feed and object detection models—preventing unnecessary loss or reloads during a rotation.&lt;h3 class=wp-block-heading&gt;&lt;a name=lifecycle_stages&gt;&lt;/a&gt;6.1. Activity Lifecycle Stages&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;Generally speaking, the Android app lifecycle consists of six main stages.&lt;h4 class=wp-block-heading&gt;1. onCreate()&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;&lt;strong&gt;Initial Setup:&lt;/strong&gt; Called when the activity is first created. This is where you perform the basic application startup logic that should occur only once.&lt;br&gt;&lt;strong&gt;UI Binding:&lt;/strong&gt; Responsible for connecting XML layout resources to the Activity and handling class instantiation.&lt;br&gt;&lt;strong&gt;Interaction Status:&lt;/strong&gt; At this stage, the activity is not yet able to interact with the user.&lt;h4 class=wp-block-heading&gt;2. onStart()&lt;/h4&gt;&lt;ul class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;Visibility:&lt;/strong&gt; Invoked as the activity becomes visible to the user, preparing it to enter the foreground.&lt;li&gt;&lt;strong&gt;App Restart:&lt;/strong&gt; This method is also called when the app is being restarted after having been stopped.&lt;li&gt;&lt;strong&gt;Interaction Status:&lt;/strong&gt; Although the UI is visible at this stage, the activity is not yet able to interact with the user.&lt;/ul&gt;&lt;h4 class=wp-block-heading&gt;3. onResume()&lt;/h4&gt;&lt;ul class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;Active Status:&lt;/strong&gt; Called when the activity starts interacting with the user. At this stage, the app is in the foreground and fully active.&lt;li&gt;&lt;strong&gt;Foreground Entry:&lt;/strong&gt; This method is invoked once the activity moves to the foreground.&lt;li&gt;&lt;strong&gt;Interaction Status:&lt;/strong&gt; The activity is now completely able to interact with the user.&lt;/ul&gt;&lt;h4 class=wp-block-heading&gt;4. onPause()&lt;/h4&gt;&lt;ul class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;System Transition:&lt;/strong&gt; Triggered when the system is about to resume a previous activity or start a new one.&lt;li&gt;&lt;strong&gt;Partial Obstruction:&lt;/strong&gt; This method is called when another activity partially covers the current activity (e.g., a semi-transparent dialog or a multi-window mode).&lt;li&gt;&lt;strong&gt;Resource Management:&lt;/strong&gt; It is primarily used to pause ongoing actions that should not continue in the background, such as animations, video playback, or &lt;strong&gt;camera previews&lt;/strong&gt;.&lt;/ul&gt;&lt;h4 class=wp-block-heading&gt;5. onStop()&lt;/h4&gt;&lt;ul class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;Visibility:&lt;/strong&gt; Executed when the activity is no longer visible to the user.&lt;li&gt;&lt;strong&gt;User Interaction:&lt;/strong&gt; This method is called when the activity has disappeared from view, typically because another activity has taken over the full screen or the user has navigated back to the home screen.&lt;li&gt;&lt;strong&gt;Resource Management:&lt;/strong&gt; Any resources that are not needed while the user is not seeing the app should be released at this stage to save system memory and power.&lt;/ul&gt;&lt;h4 class=wp-block-heading&gt;6. onDestroy()&lt;/h4&gt;&lt;ul class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;Final Call:&lt;/strong&gt; This is the final call received before the activity is destroyed.&lt;li&gt;&lt;strong&gt;Destruction Scenarios:&lt;/strong&gt; It can occur either because the activity is finishing (e.g., the user presses the ‘Back’ button or &lt;code&gt;finish()&lt;/code&gt; is called) or because the system is temporarily destroying the instance to recover valuable memory space.&lt;li&gt;&lt;strong&gt;Termination:&lt;/strong&gt; This method is invoked when the activity is being permanently removed or killed by either the system or the user.&lt;/ul&gt;&lt;h3 class=wp-block-heading&gt;&lt;a name=android_manifest&gt;&lt;/a&gt;6.2. About AndroidManifest&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;The following table summarizes the essential features and components defined within the &lt;code&gt;AndroidManifest.xml&lt;/code&gt; file:&lt;figure class=wp-block-table&gt;&lt;table class=has-fixed-layout&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Feature&lt;td&gt;Description&lt;td&gt;Core Components&lt;tr&gt;&lt;td&gt;Component Declaration&lt;td&gt;Registers the four essential building blocks of the Android system.&lt;td&gt;&lt;strong&gt;Activity:&lt;/strong&gt; UI screens.&lt;br&gt;&lt;strong&gt;Service:&lt;/strong&gt; Background tasks.&lt;br&gt;&lt;strong&gt;Receiver:&lt;/strong&gt; System signals (e.g., Boot, Battery).&lt;br&gt;&lt;strong&gt;Provider:&lt;/strong&gt; Data sharing.&lt;tr&gt;&lt;td&gt;Permission Management&lt;td&gt;Defines explicit permissions required to access sensitive device data or features.&lt;td&gt;&lt;strong&gt;Permissions:&lt;/strong&gt; &lt;code&gt;INTERNET&lt;/code&gt;, &lt;code&gt;CAMERA&lt;/code&gt;, &lt;code&gt;ACCESS_FINE_LOCATION&lt;/code&gt;, etc.&lt;tr&gt;&lt;td&gt;Basic Information Setup&lt;td&gt;Configures the app’s identity and visual presence on the system and Play Store.&lt;td&gt;&lt;strong&gt;Package Name:&lt;/strong&gt; Unique App ID.&lt;br&gt;&lt;strong&gt;Icon &amp;amp; Label:&lt;/strong&gt; Home screen visuals.&lt;br&gt;&lt;strong&gt;Theme:&lt;/strong&gt; Global design style.&lt;tr&gt;&lt;td&gt;Hardware/Software Requirements&lt;td&gt;Specifies the minimum conditions necessary for the app to be installed and run correctly.&lt;td&gt;&lt;strong&gt;SDK Versions:&lt;/strong&gt; Min/Target compatibility.&lt;br&gt;&lt;strong&gt;Uses-feature:&lt;/strong&gt; e.g., &lt;code&gt;&amp;lt;uses-feature android:name=&amp;#34;android.hardware.location.gps&amp;#34; /&amp;gt;&lt;/code&gt; prevents installation on devices without GPS.&lt;/table&gt;&lt;/figure&gt;&lt;h4 class=wp-block-heading&gt;1. Intent-filter&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;The following definitions are included within the &lt;strong&gt;intent-filter&lt;/strong&gt; element:&lt;ul class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;File Association:&lt;/strong&gt; Ensures our app is automatically executed when a user opens a specific file type, such as &lt;code&gt;.pdf&lt;/code&gt; or &lt;code&gt;.doc&lt;/code&gt; files.”&lt;/ul&gt;&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: xml; title: ; notranslate&#34;&gt;&amp;lt;activity android:name=&amp;#34;.FileViewerActivity&amp;#34;&amp;gt;&#xA;    &amp;lt;intent-filter&amp;gt;&#xA;        &amp;lt;action android:name=&amp;#34;android.intent.action.VIEW&amp;#34; /&amp;gt;&#xA;        &amp;lt;category android:name=&amp;#34;android.intent.category.DEFAULT&amp;#34; /&amp;gt;&#xA;        &amp;lt;data android:mimeType=&amp;#34;application/pdf&amp;#34; /&amp;gt;&#xA;    &amp;lt;/intent-filter&amp;gt;&#xA;&amp;lt;/activity&amp;gt;&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;ul class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;Launcher:&lt;/strong&gt; Designates which screen should be the initial entry point (the first screen to start) among multiple activities.&lt;/ul&gt;&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: xml; title: ; notranslate&#34;&gt;&amp;lt;activity&#xA;&#x9;android:name=&amp;#34;.MyHelloWorldActivity&amp;#34;&#xA;&#x9;android:exported=&amp;#34;true&amp;#34;&amp;gt;&#xA;&#x9;&amp;lt;intent-filter&amp;gt;&#xA;&#x9;&#x9;&amp;lt;action android:name=&amp;#34;android.intent.action.MAIN&amp;#34; /&amp;gt;&#xA;&#x9;&#x9;&amp;lt;category android:name=&amp;#34;android.intent.category.LAUNCHER&amp;#34; /&amp;gt;&#xA;&#x9;&amp;lt;/intent-filter&amp;gt;&#xA;&amp;lt;/activity&amp;gt;&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;h3 class=wp-block-heading&gt;&lt;a name=lifecycle_practice&gt;&lt;/a&gt;6.3. Activity Lifecycle in Practice&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;As a result, an app continuously iterates through these stages—from creation to destruction—driven by the lifecycle events. We can categorize the order of these method calls based on common user actions, as shown in the table below:&lt;figure class=wp-block-table&gt;&lt;table class=has-fixed-layout&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;User action&lt;td&gt;Lifecycle Methods Called (In Order)&lt;tr&gt;&lt;td&gt;Launch the app&lt;td&gt;&lt;code&gt;onCreate()&lt;/code&gt; → &lt;code&gt;onStart()&lt;/code&gt; → &lt;code&gt;onResume()&lt;/code&gt;&lt;tr&gt;&lt;td&gt;Press the Home button&lt;td&gt;&lt;code&gt;onPause()&lt;/code&gt; → &lt;code&gt;onStop()&lt;/code&gt;&lt;tr&gt;&lt;td&gt;Return to the app (from Home)&lt;td&gt;&lt;code&gt;onRestart()&lt;/code&gt; → &lt;code&gt;onStart()&lt;/code&gt; → &lt;code&gt;onResume()&lt;/code&gt;&lt;tr&gt;&lt;td&gt;Press the Back button&lt;td&gt;&lt;code&gt;onPause()&lt;/code&gt; → &lt;code&gt;onStop()&lt;/code&gt; → &lt;code&gt;onDestroy()&lt;/code&gt;&lt;tr&gt;&lt;td&gt;Screen Rotation (Orientation Change)&lt;td&gt;&lt;code&gt;onPause()&lt;/code&gt; → &lt;code&gt;onStop()&lt;/code&gt; → &lt;code&gt;onDestroy()&lt;/code&gt; → &lt;code&gt;onCreate()&lt;/code&gt; → &lt;code&gt;onStart()&lt;/code&gt; → &lt;code&gt;onResume()&lt;/code&gt;&lt;tr&gt;&lt;td&gt;Dialog/Popup appears (partially covers)&lt;td&gt;&lt;code&gt;onPause()&lt;/code&gt;&lt;/table&gt;&lt;/figure&gt;&lt;p class=wp-block-paragraph&gt;In the following sections, we will build a simple application using &lt;strong&gt;Android Java&lt;/strong&gt;, integrating it with the &lt;strong&gt;OpenCV Android SDK&lt;/strong&gt;.&lt;p class=wp-block-paragraph&gt;If you are already experienced with Android programming and familiar with its core concepts, you may choose to skip these introductory sections and proceed directly to the implementation details. However, for those new to the platform, these steps will provide a necessary foundation for the object detection tasks ahead.&lt;h2 class=wp-block-heading&gt;&lt;a name=helloworld_app&gt;&lt;/a&gt;7. Hello World App&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;This article is not intended for absolute beginners. I assume you already have a fundamental understanding of what an Android app is and are familiar with running tests on the Android SDK emulator. However, it is still essential to understand how to set up a basic “Hello World” project within the context of our specialized environment.&lt;p class=wp-block-paragraph&gt;Rather than starting from a blank template, we will work with a simple “Hello World” example found within the &lt;strong&gt;OpenCV samples&lt;/strong&gt; folder. To get started, you will need to create a new module for the application:&lt;p class=wp-block-paragraph&gt;&lt;strong&gt;Path:&lt;/strong&gt; File &amp;gt; New &amp;gt; New Module&lt;figure class=&#34;wp-block-image size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.new_module.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.new_module.png decoding=async width=540 height=714 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.new_module.png alt class=wp-image-142116 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.new_module.png 540w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.new_module-227x300.png 227w&#34; data-sizes=&#34;(max-width: 540px) 100vw, 540px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=540 height=714 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.new_module.png alt class=wp-image-142116 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.new_module.png 540w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.new_module-227x300.png 227w&#34; sizes=&#34;(max-width: 540px) 100vw, 540px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;h4 class=wp-block-heading&gt;1. Configuring the New Module&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;Next, you need to fill in the attributes in the &lt;strong&gt;New Module&lt;/strong&gt; setup dialog as follows. These settings ensure that your new module is correctly initialized within your project structure:&lt;div style=&#34;display:inline-block; margin: 15px 0;&#34;&gt;&lt;div id=adngin-JavaCodeGeeks_incontent_video-0 style=display:inline-block;&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;figure class=wp-block-table&gt;&lt;table class=has-fixed-layout&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Application Name&lt;td&gt;My Hello World&lt;tr&gt;&lt;td&gt;Module name&lt;td&gt;myhelloworld&lt;tr&gt;&lt;td&gt;Package name&lt;td&gt;com.example.myhelloworld&lt;tr&gt;&lt;td&gt;Language&lt;td&gt;Java&lt;tr&gt;&lt;td&gt;Minimum SDK&lt;td&gt;API 26&lt;tr&gt;&lt;td&gt;Build Configuration Language&lt;td&gt;Groovy DSL (build.gradle)&lt;/table&gt;&lt;/figure&gt;&lt;figure class=&#34;wp-block-image size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/2.create_new_module.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/2.create_new_module.png decoding=async width=801 height=626 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/2.create_new_module.png alt class=wp-image-142117 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/2.create_new_module.png 801w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/2.create_new_module-300x234.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/2.create_new_module-768x600.png 768w&#34; data-sizes=&#34;(max-width: 801px) 100vw, 801px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=801 height=626 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/2.create_new_module.png alt class=wp-image-142117 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/2.create_new_module.png 801w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/2.create_new_module-300x234.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/2.create_new_module-768x600.png 768w&#34; sizes=&#34;(max-width: 801px) 100vw, 801px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;h4 class=wp-block-heading&gt;2. Activity Template&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;Android Studio provides multiple activity styles, each offering different pre-configured features. For this project, we will focus on a simple activity creation process.&lt;p class=wp-block-paragraph&gt;However, you should select &lt;strong&gt;“No Activity”&lt;/strong&gt; from the template list. This is a critical step because the latest activity templates provided by Android Studio are based on &lt;strong&gt;AndroidX&lt;/strong&gt;, which often features library versions and structures that do not match the older &lt;strong&gt;OpenCV sample&lt;/strong&gt; configurations. By starting with “No Activity,” we can manually set up the component to ensure full compatibility with the OpenCV Android SDK.&lt;figure class=&#34;wp-block-image size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/3.choose_activity.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/3.choose_activity.png decoding=async width=798 height=627 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/3.choose_activity.png alt class=wp-image-142118 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/3.choose_activity.png 798w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/3.choose_activity-300x236.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/3.choose_activity-768x603.png 768w&#34; data-sizes=&#34;(max-width: 798px) 100vw, 798px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=798 height=627 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/3.choose_activity.png alt class=wp-image-142118 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/3.choose_activity.png 798w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/3.choose_activity-300x236.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/3.choose_activity-768x603.png 768w&#34; sizes=&#34;(max-width: 798px) 100vw, 798px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;h3 class=wp-block-heading&gt;&lt;a name=helloworld_layout&gt;&lt;/a&gt;7.1. Hello World Layouts&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;Now that the new app module, &lt;code&gt;myhelloworld&lt;/code&gt;, has been created, we need to add the functional source code. We will implement an &lt;strong&gt;Option Menu&lt;/strong&gt; that allows users to interact with the app. When a user selects an item from the menu, the text on the screen will update instantly to reflect their choice.&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/8.Hello_UI_Layout.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/8.Hello_UI_Layout-1024x532.png decoding=async width=1024 height=532 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/8.Hello_UI_Layout-1024x532.png alt class=wp-image-142141 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/8.Hello_UI_Layout-1024x532.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/8.Hello_UI_Layout-300x156.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/8.Hello_UI_Layout-768x399.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/8.Hello_UI_Layout.png 1256w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=532 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/8.Hello_UI_Layout-1024x532.png alt class=wp-image-142141 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/8.Hello_UI_Layout-1024x532.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/8.Hello_UI_Layout-300x156.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/8.Hello_UI_Layout-768x399.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/8.Hello_UI_Layout.png 1256w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;h4 class=wp-block-heading&gt;1. Defining the User Interface&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;The application screen will consist of a simple layout (typically a &lt;code&gt;TextView&lt;/code&gt;) that serves as the primary display for our app’s status and the results of user actions.&lt;h4 class=wp-block-heading&gt;2. Adding the Option Menu&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;The Option Menu is a key GUI component in Android. We will override two essential methods in our Activity class:&lt;ul class=wp-block-list&gt;&lt;li&gt;&lt;code&gt;onCreateOptionsMenu()&lt;/code&gt;: To inflate the menu resource and display it in the app bar.&lt;li&gt;&lt;code&gt;onOptionsItemSelected()&lt;/code&gt;: To handle the logic that changes the screen text based on which menu item the user clicks.&lt;/ul&gt;&lt;h4 class=wp-block-heading&gt;3. Expected Behavior&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;This exercise demonstrates the basic flow of an Android app:&lt;ol start=1 class=wp-block-list&gt;&lt;li&gt;The app initializes (Lifecycle: &lt;code&gt;onCreate&lt;/code&gt;).&lt;li&gt;The user interacts with the GUI (Option Menu).&lt;li&gt;The app responds by updating the UI components in real-time.&lt;/ol&gt;&lt;p class=wp-block-paragraph&gt;To implement the app, we need an activity and related resources the table as describe as follows:&lt;figure class=wp-block-table&gt;&lt;table class=has-fixed-layout&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;File Name&lt;td&gt;Resource Type&lt;td&gt;Description&lt;tr&gt;&lt;td&gt;MyHelloWorldActivity.java&lt;td&gt;Activity (Java)&lt;td&gt;&lt;strong&gt;Main Logic:&lt;/strong&gt; Handles lifecycle events and the logic for updating the UI based on menu interactions.&lt;tr&gt;&lt;td&gt;AndroidManifest.xml&lt;td&gt;Manifest (XML)&lt;td&gt;&lt;strong&gt;Registration:&lt;/strong&gt; Declares the activity to the Android system so it can be recognized and launched.&lt;tr&gt;&lt;td&gt;activity_main.xml&lt;td&gt;Layout (XML)&lt;td&gt;&lt;strong&gt;UI Structure:&lt;/strong&gt; Defines the placement of the &lt;code&gt;TextView&lt;/code&gt; and other visual elements.&lt;tr&gt;&lt;td&gt;option_menu.xml&lt;td&gt;Menu (XML)&lt;td&gt;&lt;strong&gt;Interaction Points:&lt;/strong&gt; Defines the individual items and icons available in the Option Menu.&lt;/table&gt;&lt;/figure&gt;&lt;h4 class=wp-block-heading&gt;4. Common Resource Folders&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;In Android development, all non-code assets— such as images, layouts, and menus—are stored in the &lt;code&gt;res&lt;/code&gt; (resource) folder. The primary goal of this folder is to &lt;strong&gt;optimize resources&lt;/strong&gt; for various screen sizes, languages, and device settings automatically. Instead of writing code to handle different environments, you provide alternative resources in specifically named folders, and the Android system selects the most appropriate one at runtime.&lt;p class=wp-block-paragraph&gt;Below are the standard folder names used within the &lt;code&gt;res&lt;/code&gt; directory and their descriptions:&lt;figure class=wp-block-table&gt;&lt;table class=has-fixed-layout&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Folder Name&lt;/strong&gt;&lt;td&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;td&gt;&lt;strong&gt;File&lt;/strong&gt;s&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;drawable&lt;/code&gt;&lt;td&gt;Contains bitmaps (PNG, JPEG), vector graphics, or XML-defined shapes and states.&lt;td&gt;&lt;code&gt;ic_launcher.png&lt;/code&gt;, &lt;code&gt;button_background.xml&lt;/code&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;layout&lt;/code&gt;&lt;td&gt;Defines the visual structure of the user interface (UI) for different screen orientations or sizes.&lt;td&gt;&lt;code&gt;activity_main.xml&lt;/code&gt;, &lt;code&gt;list_item.xml&lt;/code&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;menu&lt;/code&gt;&lt;td&gt;Defines the structure and items for options menus, context menus, or popup menus.&lt;td&gt;&lt;code&gt;main_menu.xml&lt;/code&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;values&lt;/code&gt;&lt;td&gt;Stores XML files for strings, colors, integers, and dimensions to support localization and theming.&lt;td&gt;&lt;code&gt;strings.xml&lt;/code&gt;, &lt;code&gt;colors.xml&lt;/code&gt;, &lt;code&gt;styles.xml&lt;/code&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;mipmap&lt;/code&gt;&lt;td&gt;Specifically used for application launcher icons to ensure they look sharp across different pixel densities.&lt;td&gt;&lt;code&gt;ic_launcher_round.png&lt;/code&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;raw&lt;/code&gt;&lt;td&gt;For assets like video or audio clips that should be saved in their raw form without XML compilation.&lt;td&gt;&lt;code&gt;sample_video.mp4&lt;/code&gt;, &lt;code&gt;custom_font.ttf&lt;/code&gt;&lt;/table&gt;&lt;/figure&gt;&lt;h3 class=wp-block-heading&gt;&lt;a name=create_menu&gt;&lt;/a&gt;7.2. Creating Menu&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;Since we started with a &lt;strong&gt;“No Activity”&lt;/strong&gt; template, the project structure is currently empty. Android Studio has not generated any default resource files for us. To implement our Option Menu, we must first manually create the appropriate directory within the &lt;code&gt;res&lt;/code&gt; folder.&lt;p class=wp-block-paragraph&gt;Step-by-Step Guide:&lt;ol start=1 class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;Locate the Resource Folder:&lt;/strong&gt; In the Project window, find and right-click on the &lt;strong&gt;&lt;code&gt;res&lt;/code&gt;&lt;/strong&gt; folder.&lt;li&gt;&lt;strong&gt;Create Directory:&lt;/strong&gt; Select &lt;code&gt;New&lt;/code&gt; &amp;gt; &lt;code&gt;Directory&lt;/code&gt;.&lt;li&gt;&lt;strong&gt;Naming:&lt;/strong&gt; Type &lt;strong&gt;&lt;code&gt;menu&lt;/code&gt;&lt;/strong&gt; as the directory name and press Enter.&lt;/ol&gt;&lt;figure class=&#34;wp-block-image size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu1.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu1.png decoding=async width=676 height=543 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu1.png alt class=wp-image-142120 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu1.png 676w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu1-300x241.png 300w&#34; data-sizes=&#34;(max-width: 676px) 100vw, 676px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=676 height=543 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu1.png alt class=wp-image-142120 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu1.png 676w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu1-300x241.png 300w&#34; sizes=&#34;(max-width: 676px) 100vw, 676px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;figure class=&#34;wp-block-image size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu2.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu2.png decoding=async width=316 height=86 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu2.png alt class=wp-image-142121 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu2.png 316w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu2-300x82.png 300w&#34; data-sizes=&#34;(max-width: 316px) 100vw, 316px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=316 height=86 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu2.png alt class=wp-image-142121 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu2.png 316w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu2-300x82.png 300w&#34; sizes=&#34;(max-width: 316px) 100vw, 316px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;h4 class=wp-block-heading&gt;1. Generating Menu Resource&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;Now that the &lt;code&gt;menu&lt;/code&gt; directory is ready, you can create the actual XML file that will define your menu items.&lt;p class=wp-block-paragraph&gt;Step-by-Step Guide:&lt;ol start=1 class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;Select the Directory:&lt;/strong&gt; Right-click on the newly created &lt;strong&gt;&lt;code&gt;menu&lt;/code&gt;&lt;/strong&gt; folder.&lt;li&gt;&lt;strong&gt;Create New File:&lt;/strong&gt; Select &lt;strong&gt;&lt;code&gt;New&lt;/code&gt;&lt;/strong&gt; &amp;gt; &lt;strong&gt;&lt;code&gt;Menu Resource File&lt;/code&gt;&lt;/strong&gt;.&lt;li&gt;&lt;strong&gt;Naming:&lt;/strong&gt; In the &lt;strong&gt;File name&lt;/strong&gt; field, type &lt;strong&gt;&lt;code&gt;option_menu&lt;/code&gt;&lt;/strong&gt;.&lt;li&gt;&lt;strong&gt;Completion:&lt;/strong&gt; Click &lt;strong&gt;OK&lt;/strong&gt;.&lt;/ol&gt;&lt;p class=wp-block-paragraph&gt;Once finished, you will see the &lt;code&gt;option_menu.xml&lt;/code&gt; file appear inside the &lt;code&gt;res/menu/&lt;/code&gt; directory.&lt;figure class=&#34;wp-block-image size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu3.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu3.png decoding=async width=677 height=499 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu3.png alt class=wp-image-142122 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu3.png 677w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu3-300x221.png 300w&#34; data-sizes=&#34;(max-width: 677px) 100vw, 677px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=677 height=499 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu3.png alt class=wp-image-142122 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu3.png 677w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu3-300x221.png 300w&#34; sizes=&#34;(max-width: 677px) 100vw, 677px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;figure class=&#34;wp-block-image size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu4-1.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu4-1.png decoding=async width=401 height=157 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu4-1.png alt class=wp-image-142131 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu4-1.png 401w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu4-1-300x117.png 300w&#34; data-sizes=&#34;(max-width: 401px) 100vw, 401px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=401 height=157 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu4-1.png alt class=wp-image-142131 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu4-1.png 401w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu4-1-300x117.png 300w&#34; sizes=&#34;(max-width: 401px) 100vw, 401px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;h4 class=wp-block-heading&gt;2. Menu on Palette View&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;Now, instead of writing raw XML, you can utilize the &lt;strong&gt;Palette View&lt;/strong&gt; in Android Studio to visually design your menu. This drag-and-drop interface is highly efficient for quickly prototyping the user interface.&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu5.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu5-1024x558.png decoding=async width=1024 height=558 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu5-1024x558.png alt class=wp-image-142124 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu5-1024x558.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu5-300x163.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu5-768x418.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu5.png 1199w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=558 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu5-1024x558.png alt class=wp-image-142124 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu5-1024x558.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu5-300x163.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu5-768x418.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu5.png 1199w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;p class=wp-block-paragraph&gt;The visual actions you performed in the Palette are translated into the following XML structure. Each tag represents a specific option in your menu.&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: xml; title: ; notranslate&#34;&gt;&amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;utf-8&amp;#34;?&amp;gt;&#xA;&amp;lt;menu xmlns:android=&amp;#34;http://schemas.android.com/apk/res/android&amp;#34;&#xA;    xmlns:app=&amp;#34;http://schemas.android.com/apk/res-auto&amp;#34;&amp;gt;&#xA;    &#xA;    &amp;lt;item&#xA;        android:id=&amp;#34;@+id/option_my_name&amp;#34;&#xA;        android:title=&amp;#34;My Hello World Activity&amp;#34;&#xA;        app:showAsAction=&amp;#34;never&amp;#34; /&amp;gt;&#xA;        &#xA;    &amp;lt;item&#xA;        android:id=&amp;#34;@+id/option_greeting&amp;#34;&#xA;        android:title=&amp;#34;Greeting My Hello World&amp;#34;&#xA;        app:showAsAction=&amp;#34;never&amp;#34; /&amp;gt;&#xA;&amp;lt;/menu&amp;gt;&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;h4 class=wp-block-heading&gt;3. Menu Layout&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;This means you have created both the &lt;strong&gt;‘My Hello World Activity’&lt;/strong&gt; and the &lt;strong&gt;‘Greeting My Hello World’&lt;/strong&gt; messages, allowing the screen text to change dynamically whenever a user selects an option from the menu. The final result is as follows:&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu6.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu6-1024x503.png decoding=async width=1024 height=503 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu6-1024x503.png alt class=wp-image-142125 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu6-1024x503.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu6-300x147.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu6-768x377.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu6.png 1260w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=503 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu6-1024x503.png alt class=wp-image-142125 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu6-1024x503.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu6-300x147.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu6-768x377.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.create_option_menu6.png 1260w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;p class=wp-block-paragraph&gt;Once the option menu is created, you need a layout to which the menu will be attached before the main activity is finalized. The next step is to create the main layout. In Android Studio,&lt;figure class=&#34;wp-block-image size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout1.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout1.png decoding=async width=665 height=643 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout1.png alt class=wp-image-142126 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout1.png 665w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout1-300x290.png 300w&#34; data-sizes=&#34;(max-width: 665px) 100vw, 665px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=665 height=643 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout1.png alt class=wp-image-142126 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout1.png 665w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout1-300x290.png 300w&#34; sizes=&#34;(max-width: 665px) 100vw, 665px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;p class=wp-block-paragraph&gt;select &lt;strong&gt;New &amp;gt; Layout Resource File&lt;/strong&gt; to generate the layout file for your activity.&lt;figure class=&#34;wp-block-image size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout2.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout2.png decoding=async width=691 height=498 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout2.png alt class=wp-image-142127 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout2.png 691w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout2-300x216.png 300w&#34; data-sizes=&#34;(max-width: 691px) 100vw, 691px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=691 height=498 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout2.png alt class=wp-image-142127 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout2.png 691w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout2-300x216.png 300w&#34; sizes=&#34;(max-width: 691px) 100vw, 691px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;p class=wp-block-paragraph&gt;In the &lt;strong&gt;New Layout Resource File&lt;/strong&gt; dialog, enter &lt;code&gt;activity_main.xml&lt;/code&gt; as the file name and set &lt;strong&gt;RelativeLayout&lt;/strong&gt; as the root element. RelativeLayout is one of the standard layout managers provided by Google; for more detailed information, you can refer to Google’s official Android Developer documentation.&lt;figure class=&#34;wp-block-image size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout3.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout3.png decoding=async width=265 height=172 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout3.png alt class=wp-image-142128&gt;&lt;noscript&gt;&lt;img decoding=async width=265 height=172 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout3.png alt class=wp-image-142128&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;p class=wp-block-paragraph&gt;Click &lt;strong&gt;OK&lt;/strong&gt; to create the empty layout. You can then find the &lt;code&gt;activity_main.xml&lt;/code&gt; file under the &lt;strong&gt;res/layout&lt;/strong&gt; folder, initialized with the &lt;strong&gt;RelativeLayout&lt;/strong&gt; as its root element.&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout4.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout4-1024x540.png decoding=async width=1024 height=540 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout4-1024x540.png alt class=wp-image-142129 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout4-1024x540.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout4-300x158.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout4-768x405.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout4.png 1257w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=540 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout4-1024x540.png alt class=wp-image-142129 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout4-1024x540.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout4-300x158.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout4-768x405.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout4.png 1257w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;p class=wp-block-paragraph&gt;We need a &lt;strong&gt;TextView&lt;/strong&gt; to display the text that changes based on the user’s selection. The TextView’s content can be updated via a listener or logic that responds to component actions. You can find more details regarding the various attributes of this class on Google’s official Android Developer site.&lt;pre class=wp-block-code&gt;&lt;code&gt;&amp;lt;TextView&#xA;&#x9;android:id=&amp;#34;@+id/statusTextView&amp;#34;&#xA;&#x9;android:layout_width=&amp;#34;wrap_content&amp;#34;&#xA;&#x9;android:layout_height=&amp;#34;wrap_content&amp;#34;&#xA;&#x9;android:layout_centerInParent=&amp;#34;true&amp;#34;&#xA;&#x9;android:text=&amp;#34;My Hello World Activity&amp;#34;&#xA;&#x9;android:textSize=&amp;#34;24sp&amp;#34;&#xA;&#x9;android:textColor=&amp;#34;#000000&amp;#34; /&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout5.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout5-1024x500.png decoding=async width=1024 height=500 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout5-1024x500.png alt class=wp-image-142130 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout5-1024x500.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout5-300x147.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout5-768x375.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout5.png 1265w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=500 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout5-1024x500.png alt class=wp-image-142130 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout5-1024x500.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout5-300x147.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout5-768x375.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/6.create_layout5.png 1265w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;p class=wp-block-paragraph&gt;At this point, we have an app where the on-screen text changes based on user menu selections, utilizing &lt;code&gt;option_menu.xml&lt;/code&gt; and &lt;code&gt;activity_main.xml&lt;/code&gt;. Finally, we need to define and manage our activities by configuring the &lt;strong&gt;AndroidManifest.xml&lt;/strong&gt;, which serves as the formal specification of the app.&lt;h4 class=wp-block-heading&gt;4. AndroidManifest&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;The Android system automatically recognizes the &lt;strong&gt;AndroidManifest.xml&lt;/strong&gt; file, reads its contents, and executes the appropriate activity to launch the application. The following source code demonstrates how this specification is structured:&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: xml; title: ; notranslate&#34;&gt;&amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;utf-8&amp;#34;?&amp;gt;&#xA;&amp;lt;manifest xmlns:android=&amp;#34;http://schemas.android.com/apk/res/android&amp;#34;&#xA;    package=&amp;#34;com.example.myhelloworld&amp;#34;&amp;gt;&#xA;&#xA;    &amp;lt;application&#xA;        android:allowBackup=&amp;#34;true&amp;#34;&#xA;        android:icon=&amp;#34;@drawable/icon&amp;#34;&#xA;        android:label=&amp;#34;My App&amp;#34;&#xA;        android:theme=&amp;#34;@style/Theme.AppCompat.Light.DarkActionBar&amp;#34;&amp;gt;&#xA;&#xA;        &amp;lt;activity&#xA;            android:name=&amp;#34;.MyHelloWorldActivity&amp;#34;&#xA;            android:exported=&amp;#34;true&amp;#34;&amp;gt;&#xA;            &amp;lt;intent-filter&amp;gt;&#xA;                &amp;lt;action android:name=&amp;#34;android.intent.action.MAIN&amp;#34; /&amp;gt;&#xA;                &amp;lt;category android:name=&amp;#34;android.intent.category.LAUNCHER&amp;#34; /&amp;gt;&#xA;            &amp;lt;/intent-filter&amp;gt;&#xA;        &amp;lt;/activity&amp;gt;&#xA;&#xA;    &amp;lt;/application&amp;gt;&#xA;&amp;lt;/manifest&amp;gt;&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;h4 class=wp-block-heading&gt;7. MyHelloWorldActivity&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;Now, let’s implement the logic for the Activity to handle user interactions and bridge the resources and layouts we have created. To begin, select &lt;strong&gt;New &amp;gt; Java Class&lt;/strong&gt; from the menu and name the class &lt;strong&gt;‘MyHelloWorldActivity’&lt;/strong&gt;.&lt;figure class=&#34;wp-block-image size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/4.source_create_activity.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/4.source_create_activity.png decoding=async width=627 height=441 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/4.source_create_activity.png alt class=wp-image-142119 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/4.source_create_activity.png 627w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/4.source_create_activity-300x211.png 300w&#34; data-sizes=&#34;(max-width: 627px) 100vw, 627px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=627 height=441 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/4.source_create_activity.png alt class=wp-image-142119 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/4.source_create_activity.png 627w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/4.source_create_activity-300x211.png 300w&#34; sizes=&#34;(max-width: 627px) 100vw, 627px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;p class=wp-block-paragraph&gt;The complete source code for &lt;strong&gt;‘MyHelloWorldActivity’&lt;/strong&gt; is provided below, demonstrating how to integrate the layout, handle menu selections, and update the UI dynamically:&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: java; title: ; notranslate&#34;&gt;package com.example.myhelloworld;&#xA;&#xA;import android.os.Bundle;&#xA;import android.support.v7.app.AppCompatActivity;&#xA;import android.view.Menu;&#xA;import android.view.MenuInflater;&#xA;import android.view.MenuItem;&#xA;import android.widget.TextView;&#xA;&#xA;public class MyHelloWorldActivity extends AppCompatActivity {&#xA;&#xA;    // Declare a TextView variable to handle dynamic text updates.&#xA;    private TextView statusTextView;&#xA;&#xA;    @Override&#xA;    protected void onCreate(Bundle savedInstanceState) {&#xA;        super.onCreate(savedInstanceState);&#xA;&#xA;        // Link the activity_main.xml layout to this Activity.&#xA;        setContentView(R.layout.activity_main);&#xA;&#xA;        // Initialize the TextView by linking it to its corresponding ID defined in the XML.&#xA;        statusTextView = (TextView) findViewById(R.id.statusTextView);&#xA;    }&#xA;&#xA;    @Override&#xA;    public boolean onCreateOptionsMenu(Menu menu) {&#xA;        MenuInflater inflater = getMenuInflater();&#xA;        inflater.inflate(R.menu.option_menu, menu);&#xA;        return true;&#xA;    }&#xA;&#xA;    @Override&#xA;    public boolean onOptionsItemSelected(MenuItem item) {&#xA;        int id = item.getItemId();&#xA;&#xA;        if (id == R.id.option_my_name) {&#xA;            statusTextView.setText(&amp;#34;Selected: My name is OpenCV!&amp;#34;);&#xA;            return true;&#xA;        }&#xA;&#xA;        if (id == R.id.option_greeting) {&#xA;            statusTextView.setText(&amp;#34;Selected: Nice to meet you!&amp;#34;);&#xA;            return true;&#xA;        }&#xA;&#xA;        return super.onOptionsItemSelected(item);&#xA;    }&#xA;}&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;p class=wp-block-paragraph&gt;In the source code, two key methods handle the user interface setup: &lt;code&gt;onCreate()&lt;/code&gt;, which initializes the main activity, and &lt;code&gt;onCreateOptionsMenu()&lt;/code&gt;, which populates the GUI with the options menu.&lt;p class=wp-block-paragraph&gt;The &lt;code&gt;setContentView()&lt;/code&gt; method is called within &lt;code&gt;onCreate()&lt;/code&gt; to inflate and display the &lt;code&gt;activity_main.xml&lt;/code&gt; layout file.&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: java; title: ; notranslate&#34;&gt;@Override&#xA;protected void onCreate(Bundle savedInstanceState) {&#xA;&#x9;super.onCreate(savedInstanceState);&#xA;&#x9;// Link the activity_main.xml layout to this Activity.&#xA;&#x9;setContentView(R.layout.activity_main);&#xA;&#x9;// Initialize the TextView by linking it to its corresponding ID defined in the XML.&#xA;&#x9;statusTextView = (TextView) findViewById(R.id.statusTextView);&#xA;}&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;p class=wp-block-paragraph&gt;Inside &lt;code&gt;onCreateOptionsMenu()&lt;/code&gt;, we populate the menu by calling the &lt;code&gt;inflate()&lt;/code&gt; method of the &lt;code&gt;MenuInflater&lt;/code&gt;, which links the &lt;code&gt;option_menu.xml&lt;/code&gt; resource to the Activity’s menu bar&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: java; title: ; notranslate&#34;&gt;@Override&#xA;public boolean onCreateOptionsMenu(Menu menu) {&#xA;&#x9;MenuInflater inflater = getMenuInflater();&#xA;&#x9;inflater.inflate(R.menu.option_menu, menu);&#xA;&#x9;return true;&#xA;}&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;p class=wp-block-paragraph&gt;In the &lt;code&gt;onOptionsItemSelected()&lt;/code&gt; method, we define the logic to update the text on the screen whenever a user selects an item from the options menu.&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: java; title: ; notranslate&#34;&gt;@Override&#xA;public boolean onOptionsItemSelected(MenuItem item) {&#xA;&#x9;int id = item.getItemId();&#xA;&#xA;&#x9;if (id == R.id.option_my_name) {&#xA;&#x9;&#x9;// Display the string when the user selects &amp;#39;option_my_name&amp;#39;&#xA;&#x9;&#x9;statusTextView.setText(&amp;#34;Selected: My name is OpenCV!&amp;#34;);&#xA;&#x9;&#x9;return true;&#xA;&#x9;}&#xA;&#xA;&#x9;if (id == R.id.option_greeting) {&#xA;&#x9;&#x9;// Display the string when the user selects &amp;#39;option_greeting&amp;#39;&#xA;&#x9;&#x9;statusTextView.setText(&amp;#34;Selected: Nice to meet you!&amp;#34;);&#xA;&#x9;&#x9;return true;&#xA;&#x9;}&#xA;&#xA;&#x9;return super.onOptionsItemSelected(item);&#xA;}&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;p class=wp-block-paragraph&gt;Using &lt;strong&gt;Android Studio&lt;/strong&gt;, you can build and launch your ‘Hello World’ app directly on a physical device. Once running, your results should match the interface shown in the following image:&lt;figure class=&#34;wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-4 is-layout-flex wp-block-gallery-is-layout-flex&#34;&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_2-1.jpg&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_2-1-1024x620.jpg decoding=async width=1024 height=620 data-id=142136 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_2-1-1024x620.jpg alt class=wp-image-142136 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_2-1-1024x620.jpg 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_2-1-300x182.jpg 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_2-1-768x465.jpg 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_2-1-1536x931.jpg 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_2-1-2048x1241.jpg 2048w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=620 data-id=142136 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_2-1-1024x620.jpg alt class=wp-image-142136 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_2-1-1024x620.jpg 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_2-1-300x182.jpg 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_2-1-768x465.jpg 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_2-1-1536x931.jpg 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_2-1-2048x1241.jpg 2048w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_3-1.jpg&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_3-1-1024x620.jpg decoding=async width=1024 height=620 data-id=142137 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_3-1-1024x620.jpg alt class=wp-image-142137 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_3-1-1024x620.jpg 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_3-1-300x182.jpg 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_3-1-768x465.jpg 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_3-1-1536x931.jpg 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_3-1-2048x1241.jpg 2048w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=620 data-id=142137 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_3-1-1024x620.jpg alt class=wp-image-142137 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_3-1-1024x620.jpg 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_3-1-300x182.jpg 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_3-1-768x465.jpg 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_3-1-1536x931.jpg 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_3-1-2048x1241.jpg 2048w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_4-1.jpg&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_4-1-1024x620.jpg decoding=async width=1024 height=620 data-id=142138 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_4-1-1024x620.jpg alt class=wp-image-142138 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_4-1-1024x620.jpg 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_4-1-300x182.jpg 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_4-1-768x465.jpg 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_4-1-1536x931.jpg 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_4-1-2048x1241.jpg 2048w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=620 data-id=142138 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_4-1-1024x620.jpg alt class=wp-image-142138 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_4-1-1024x620.jpg 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_4-1-300x182.jpg 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_4-1-768x465.jpg 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_4-1-1536x931.jpg 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/7.exec_hello_4-1-2048x1241.jpg 2048w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/figure&gt;&lt;p class=wp-block-paragraph&gt;So far, we have explored the fundamental relationship between &lt;strong&gt;Activities&lt;/strong&gt; and &lt;strong&gt;GUI&lt;/strong&gt; components in Android. In the next section, we will build upon this foundation to create our own custom &lt;strong&gt;OpenCV&lt;/strong&gt; samples, integrating computer vision capabilities into our mobile environment.&lt;h2 class=wp-block-heading&gt;&lt;a name=helloopencv_app&gt;&lt;/a&gt;8. Hello OpenCV App&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;In the previous section, we built a simple ‘Hello World’ app. However, developing an application for &lt;strong&gt;object detection&lt;/strong&gt; using the &lt;strong&gt;OpenCV library&lt;/strong&gt; requires a more specialized approach.&lt;p class=wp-block-paragraph&gt;Utilizing OpenCV as a vision library allows us to manipulate and manage image sources via camera functions. The goal of this section is to create a simple camera application where you can process live image sources using &lt;strong&gt;OpenCV methods and callbacks&lt;/strong&gt;. Before we begin processing frames, our application must first obtain the necessary &lt;strong&gt;Camera Permissions&lt;/strong&gt; by declaring them in the &lt;code&gt;AndroidManifest.xml&lt;/code&gt; file.&lt;h3 class=wp-block-heading&gt;&lt;a name=components&gt;&lt;/a&gt;8.1. Components and Resources&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;While the development process follows a similar workflow to the ‘Hello World’ app, we will introduce several new classes and resources specific to OpenCV integration. The following list outlines the Project components and resources we are about to implement:&lt;figure class=wp-block-table&gt;&lt;table class=has-fixed-layout&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Category&lt;td&gt;File Name&lt;td&gt;Description&lt;tr&gt;&lt;td&gt;Source code(Java)&lt;td&gt;MyHelloOpenCVActivity.java&lt;td&gt;The primary Activity class that manages OpenCV initialization and updates the UI with specific messages based on the user’s menu selections.&lt;tr&gt;&lt;td&gt;Manifest File&lt;td&gt;AndroidManifest.xml&lt;td&gt;The essential configuration file that defines app components and declares the required hardware permissions, such as Camera access.&lt;tr&gt;&lt;td&gt;Layout File&lt;td&gt;activity_main.xml&lt;td&gt;The XML definition of the user interface, acting as the container for both the camera view and UI elements.&lt;tr&gt;&lt;td&gt;Menu File&lt;td&gt;option_menu.xml&lt;td&gt;Defines the interactive menu items that allow the user to trigger different OpenCV processing modes or messages.&lt;tr&gt;&lt;td&gt;String Resource File&lt;td&gt;string.xml&lt;td&gt;A centralized resource file for managing all text constants, ensuring clean separation between logic and UI content.&lt;/table&gt;&lt;/figure&gt;&lt;h3 class=wp-block-heading&gt;&lt;a name=opencv_layout&gt;&lt;/a&gt;8.2. Hello OpenCV Layout&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;In our layout, we use a LinearLayout as the root container. The focal point of this layout is the JavaCameraView class, which is provided by the OpenCV Android SDK. As the name suggests, JavaCameraView is a specialized view that inherits from android.view.SurfaceView, designed specifically to handle real-time camera frames efficiently.&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: xml; title: ; notranslate&#34;&gt;&amp;lt;LinearLayout xmlns:android=&amp;#34;http://schemas.android.com/apk/res/android&amp;#34;&#xA;    xmlns:tools=&amp;#34;http://schemas.android.com/tools&amp;#34;&#xA;    xmlns:opencv=&amp;#34;http://schemas.android.com/apk/res-auto&amp;#34;&#xA;    android:layout_width=&amp;#34;match_parent&amp;#34;&#xA;    android:layout_height=&amp;#34;match_parent&amp;#34; &amp;gt;&#xA;&#xA;    &amp;lt;org.opencv.android.JavaCameraView&#xA;        android:layout_width=&amp;#34;fill_parent&amp;#34;&#xA;        android:layout_height=&amp;#34;fill_parent&amp;#34;&#xA;        android:id=&amp;#34;@+id/camera_java_surface_view&amp;#34; /&amp;gt;&#xA;&#xA;&amp;lt;/LinearLayout&amp;gt;&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;p class=wp-block-paragraph&gt;You can visualize the GUI design and layout structure directly within the &lt;strong&gt;Palette&lt;/strong&gt; and &lt;strong&gt;Design&lt;/strong&gt; views of the Android Studio Layout Editor.&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.activity_main-1.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.activity_main-1-1024x471.png decoding=async width=1024 height=471 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.activity_main-1-1024x471.png alt class=wp-image-142144 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.activity_main-1-1024x471.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.activity_main-1-300x138.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.activity_main-1-768x354.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.activity_main-1.png 1336w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=471 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.activity_main-1-1024x471.png alt class=wp-image-142144 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.activity_main-1-1024x471.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.activity_main-1-300x138.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.activity_main-1-768x354.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.activity_main-1.png 1336w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;h4 class=wp-block-heading&gt;1. Menu Layout&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;The menu structure in this section is more advanced than our previous example. We utilize the element with the android:checkableBehavior=”single” attribute, ensuring that the user can only select one option at a time—similar to a radio button interaction.&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: xml; title: ; notranslate&#34;&gt;&amp;lt;menu xmlns:android=&amp;#34;http://schemas.android.com/apk/res/android&amp;#34;&#xA;    xmlns:app=&amp;#34;http://schemas.android.com/apk/res-auto&amp;#34;&amp;gt;&#xA;    &amp;lt;group android:checkableBehavior=&amp;#34;single&amp;#34;&amp;gt;&#xA;        &amp;lt;item&#xA;            android:id=&amp;#34;@+id/hellocv&amp;#34;&#xA;            android:showAsAction=&amp;#34;ifRoom|withText&amp;#34;&#xA;            android:title=&amp;#34;@string/cv_message&amp;#34; /&amp;gt;&#xA;        &amp;lt;item&#xA;            android:id=&amp;#34;@+id/hellocv_title&amp;#34;&#xA;            android:title=&amp;#34;@string/normal&amp;#34;&amp;gt;&#xA;            &amp;lt;menu&amp;gt;&#xA;                &amp;lt;group android:checkableBehavior=&amp;#34;single&amp;#34;&amp;gt;&#xA;                    &amp;lt;item android:id=&amp;#34;@+id/normal_message&amp;#34;&#xA;                        android:title=&amp;#34;@string/normal&amp;#34;&#xA;                        android:checked=&amp;#34;true&amp;#34; /&amp;gt;&#xA;                    &amp;lt;item android:id=&amp;#34;@+id/cv_message1&amp;#34;&#xA;                        android:title=&amp;#34;@string/cv_message1&amp;#34;/&amp;gt;&#xA;                    &amp;lt;item android:id=&amp;#34;@+id/cv_message2&amp;#34;&#xA;                        android:title=&amp;#34;@string/cv_message2&amp;#34; /&amp;gt;&#xA;                &amp;lt;/group&amp;gt;&#xA;            &amp;lt;/menu&amp;gt;&#xA;        &amp;lt;/item&amp;gt;&#xA;    &amp;lt;/group&amp;gt;&#xA;&#xA;&amp;lt;/menu&amp;gt;&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;h4 class=wp-block-heading&gt;2. String Resource&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;Starting with ‘@’ symbol is a special identifier called &lt;strong&gt;“Resource Reference&lt;/strong&gt;” that you can access a string from the other resource or file by the id and this time, string.xml file.&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/2.option_menu.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/2.option_menu-1024x484.png decoding=async width=1024 height=484 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/2.option_menu-1024x484.png alt class=wp-image-142143 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/2.option_menu-1024x484.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/2.option_menu-300x142.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/2.option_menu-768x363.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/2.option_menu.png 1274w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=484 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/2.option_menu-1024x484.png alt class=wp-image-142143 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/2.option_menu-1024x484.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/2.option_menu-300x142.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/2.option_menu-768x363.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/2.option_menu.png 1274w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;p class=wp-block-paragraph&gt;In the &lt;code&gt;strings.xml&lt;/code&gt; file, you define string resources associated with unique IDs. These IDs serve as references that allow the system to dynamically substitute the appropriate text based on varying conditions, such as the device’s language settings or specific app states.&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: xml; title: ; notranslate&#34;&gt;&amp;lt;resources&amp;gt;&#xA;    &amp;lt;string name=&amp;#34;app_name&amp;#34;&amp;gt;My Hello OpenCV&amp;lt;/string&amp;gt;&#xA;    &amp;lt;string name=&amp;#34;title_hellocv&amp;#34;&amp;gt;Welcome to the OpenCV World&amp;lt;/string&amp;gt;&#xA;    &amp;lt;string name=&amp;#34;mode_default&amp;#34;&amp;gt;normal mode&amp;lt;/string&amp;gt;&#xA;    &amp;lt;string name=&amp;#34;normal&amp;#34;&amp;gt;normal message&amp;lt;/string&amp;gt;&#xA;    &amp;lt;string name=&amp;#34;cv_message1&amp;#34;&amp;gt;cv message_1&amp;lt;/string&amp;gt;&#xA;    &amp;lt;string name=&amp;#34;cv_message2&amp;#34;&amp;gt;cv message_2&amp;lt;/string&amp;gt;&#xA;    &amp;lt;string name=&amp;#34;message1&amp;#34;&amp;gt;Welcome to the OpenCV World&amp;lt;/string&amp;gt;&#xA;    &amp;lt;string name=&amp;#34;message2&amp;#34;&amp;gt;Hello from the OpenCV World&amp;lt;/string&amp;gt;&#xA;    &amp;lt;string name=&amp;#34;message3&amp;#34;&amp;gt;Greetings from the OpenCV World&amp;lt;/string&amp;gt;&#xA;&amp;lt;/resources&amp;gt;&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;h4 class=wp-block-heading&gt;3. Android Manifest&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;The &lt;code&gt;AndroidManifest.xml&lt;/code&gt; file defines the entry point of the application. By placing the &lt;code&gt;&amp;lt;intent-filter&amp;gt;&lt;/code&gt; element within the declaration for &lt;code&gt;MyHelloOpenCVActivity&lt;/code&gt;, we designate this class as the main activity that launches when the user opens the app.&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: xml; title: ; notranslate&#34;&gt;&amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;utf-8&amp;#34;?&amp;gt;&#xA;&amp;lt;manifest xmlns:android=&amp;#34;http://schemas.android.com/apk/res/android&amp;#34;&#xA;    package=&amp;#34;com.example.myhelloopencv&amp;#34;&amp;gt;&#xA;&#xA;    &amp;lt;application&#xA;        android:allowBackup=&amp;#34;true&amp;#34;&#xA;        android:icon=&amp;#34;@drawable/icon&amp;#34;&#xA;        android:label=&amp;#34;My App&amp;#34;&amp;gt;&#xA;&#xA;        &amp;lt;activity&#xA;            android:name=&amp;#34;MyHelloOpenCVActivity&amp;#34;&#xA;            android:exported=&amp;#34;true&amp;#34;&amp;gt;&#xA;            &amp;lt;intent-filter&amp;gt;&#xA;                &amp;lt;action android:name=&amp;#34;android.intent.action.MAIN&amp;#34; /&amp;gt;&#xA;                &amp;lt;category android:name=&amp;#34;android.intent.category.LAUNCHER&amp;#34; /&amp;gt;&#xA;            &amp;lt;/intent-filter&amp;gt;&#xA;        &amp;lt;/activity&amp;gt;&#xA;&#xA;    &amp;lt;/application&amp;gt;&#xA;&#xA;    &amp;lt;uses-permission android:name=&amp;#34;android.permission.CAMERA&amp;#34;/&amp;gt;&#xA;&#xA;    &amp;lt;uses-feature android:name=&amp;#34;android.hardware.camera&amp;#34; android:required=&amp;#34;false&amp;#34;/&amp;gt;&#xA;    &amp;lt;uses-feature android:name=&amp;#34;android.hardware.camera.autofocus&amp;#34; android:required=&amp;#34;false&amp;#34;/&amp;gt;&#xA;    &amp;lt;uses-feature android:name=&amp;#34;android.hardware.camera.front&amp;#34; android:required=&amp;#34;false&amp;#34;/&amp;gt;&#xA;    &amp;lt;uses-feature android:name=&amp;#34;android.hardware.camera.front.autofocus&amp;#34; android:required=&amp;#34;false&amp;#34;/&amp;gt;&#xA;    &amp;lt;uses-permission android:name=&amp;#34;android.permission.WRITE_EXTERNAL_STORAGE&amp;#34; /&amp;gt;&#xA;&#xA;&amp;lt;/manifest&amp;gt;&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;p class=wp-block-paragraph&gt;It is crucial to define the &lt;code&gt;&amp;lt;uses-permission&amp;gt;&lt;/code&gt; element carefully, as it informs the Android system and the user which protected features the app needs to access. By specifying a permission name—such as &lt;code&gt;android.permission.WRITE_EXTERNAL_STORAGE&lt;/code&gt;—the application explicitly requests the necessary rights to perform sensitive operations, like saving files to the device’s storage&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: xml; title: ; notranslate&#34;&gt;&amp;lt;uses-permission android:name=&amp;#34;android.permission.WRITE_EXTERNAL_STORAGE&amp;#34; /&amp;gt;&#xA;&amp;lt;uses-permission android:name=&amp;#34;android.permission.CAMERA&amp;#34;/&amp;gt;&#xA;    &amp;lt;uses-feature android:name=&amp;#34;android.hardware.camera&amp;#34; android:required=&amp;#34;false&amp;#34;/&amp;gt;&#xA;    &amp;lt;uses-feature android:name=&amp;#34;android.hardware.camera.autofocus&amp;#34; android:required=&amp;#34;false&amp;#34;/&amp;gt;&#xA;    &amp;lt;uses-feature android:name=&amp;#34;android.hardware.camera.front&amp;#34; android:required=&amp;#34;false&amp;#34;/&amp;gt;&#xA;    &amp;lt;uses-feature android:name=&amp;#34;android.hardware.camera.front.autofocus&amp;#34; android:required=&amp;#34;false&amp;#34;/&amp;gt;&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;p class=wp-block-paragraph&gt;While we use the &lt;code&gt;&amp;lt;uses-permission&amp;gt;&lt;/code&gt; element to request authorization from the Android system to access sensitive data or hardware, we can further refine our app’s requirements using the &lt;code&gt;&amp;lt;uses-feature&amp;gt;&lt;/code&gt; element. In this project, we explicitly request permissions for both &lt;strong&gt;Camera&lt;/strong&gt; and &lt;strong&gt;External Storage&lt;/strong&gt;. By declaring these, we ensure the app has the necessary environment to capture and process images while also being able to save or load data as needed.&lt;h3 class=wp-block-heading&gt;&lt;a name=main_class&gt;&lt;/a&gt;8.3. MyHelloOpenCVActivity&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;The main class, MyHelloOpenCVActivity, extends CameraActivity. Note that CameraActivity itself is a specialized class provided by the OpenCV Android SDK, which inherits from the standard Android Activity class to provide built-in management for camera lifecycle and permissions.&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: java; title: ; notranslate&#34;&gt;package com.example.myhelloopencv;&#xA;&#xA;import android.os.Bundle;&#xA;import android.util.Log;&#xA;import android.view.Menu;&#xA;import android.view.MenuItem;&#xA;import android.view.SurfaceView;&#xA;import android.view.WindowManager;&#xA;import android.widget.Toast;&#xA;&#xA;import org.opencv.android.CameraActivity;&#xA;import org.opencv.android.CameraBridgeViewBase;&#xA;import org.opencv.android.OpenCVLoader;&#xA;import org.opencv.core.Mat;&#xA;import org.opencv.core.Point;&#xA;import org.opencv.core.Scalar;&#xA;import org.opencv.imgproc.Imgproc;&#xA;&#xA;import java.util.Collections;&#xA;import java.util.List;&#xA;&#xA;public class MyHelloOpenCVActivity extends CameraActivity implements CameraBridgeViewBase.CvCameraViewListener2 {&#xA;    private static final String TAG = &amp;#34;CVSample::Activity&amp;#34;;&#xA;    private CameraBridgeViewBase mOpenCvCameraView;&#xA;&#xA;    private static String mLabelMessage ;&#xA;    private static  double mCenterX, mCenterY;&#xA;&#xA;    public MyHelloOpenCVActivity() {&#xA;        Log.i(TAG, &amp;#34;Instantiated new &amp;#34; + this.getClass());&#xA;    }&#xA;&#xA;    @Override&#xA;    protected void onCreate(Bundle savedInstanceState) {&#xA;        Log.i(TAG, &amp;#34;called onCreate&amp;#34;);&#xA;        super.onCreate(savedInstanceState);&#xA;&#xA;        //! [ocv_loader_init]&#xA;        if (OpenCVLoader.initLocal()) {&#xA;            Log.i(TAG, &amp;#34;OpenCV loaded successfully&amp;#34;);&#xA;        } else {&#xA;            Log.e(TAG, &amp;#34;OpenCV initialization failed!&amp;#34;);&#xA;            (Toast.makeText(this, &amp;#34;OpenCV initialization failed!&amp;#34;, Toast.LENGTH_LONG)).show();&#xA;            return;&#xA;        }&#xA;        //! [ocv_loader_init]&#xA;&#xA;        //! [keep_screen]&#xA;        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);&#xA;        //! [keep_screen]&#xA;&#xA;        setContentView(R.layout.activity_main);&#xA;&#xA;        mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.camera_hellocv_java_surface_view);&#xA;&#xA;        mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);&#xA;&#xA;        mOpenCvCameraView.setCvCameraViewListener(this);&#xA;    }&#xA;&#xA;    @Override&#xA;    public void onPause()&#xA;    {&#xA;        super.onPause();&#xA;        if (mOpenCvCameraView != null)&#xA;            mOpenCvCameraView.disableView();&#xA;    }&#xA;&#xA;    @Override&#xA;    public void onResume()&#xA;    {&#xA;        super.onResume();&#xA;        if (mOpenCvCameraView != null)&#xA;            mOpenCvCameraView.enableView();&#xA;    }&#xA;&#xA;    @Override&#xA;    public void onDestroy() {&#xA;        super.onDestroy();&#xA;        if (mOpenCvCameraView != null)&#xA;            mOpenCvCameraView.disableView();&#xA;    }&#xA;&#xA;    @Override&#xA;    protected List&amp;lt;? extends CameraBridgeViewBase&amp;gt; getCameraViewList() {&#xA;        return Collections.singletonList(mOpenCvCameraView);&#xA;    }&#xA;&#xA;    @Override&#xA;    public boolean onCreateOptionsMenu(Menu menu) {&#xA;        super.onCreateOptionsMenu(menu);&#xA;        getMenuInflater().inflate(R.menu.option_menu, menu);&#xA;        return true;&#xA;    }&#xA;&#xA;    @Override&#xA;    public boolean onOptionsItemSelected(MenuItem item) {&#xA;        boolean retBool;&#xA;&#xA;        int id = item.getItemId();&#xA;        if(id == R.id.normal_message)&#xA;        {&#xA;            mLabelMessage = &amp;#34;[Normal message]&amp;#34; + getString(R.string.message1);&#xA;            item.setChecked(true);&#xA;            retBool = true;&#xA;        }&#xA;        else if(id == R.id.cv_message1)&#xA;        {&#xA;            mLabelMessage = &amp;#34;[CV message1]&amp;#34; + getResources().getString(R.string.message2);&#xA;            item.setChecked(true);&#xA;            retBool = true;&#xA;        }&#xA;        else if(id == R.id.cv_message2)&#xA;        {&#xA;            mLabelMessage = &amp;#34;[CV message2]&amp;#34; + getResources().getString(R.string.message3);&#xA;            item.setChecked(true);&#xA;            retBool = true;&#xA;        }&#xA;        else&#xA;        {&#xA;            retBool = super.onOptionsItemSelected(item);&#xA;        }&#xA;        return retBool;&#xA;    }&#xA;&#xA;    @Override&#xA;    public void onCameraViewStarted(int width, int height) {&#xA;        mCenterX =  (double) width /2;&#xA;        mCenterY =  (double) height /2;&#xA;    }&#xA;&#xA;    @Override&#xA;    public void onCameraViewStopped() {&#xA;&#xA;    }&#xA;&#xA;    @Override&#xA;    public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {&#xA;        Mat matFrame = inputFrame.rgba();&#xA;&#xA;        if(mLabelMessage != null)&#xA;        {&#xA;            Imgproc.putText(matFrame, mLabelMessage, new Point(mCenterX/4, mCenterY), Imgproc.FONT_HERSHEY_SIMPLEX, 2.2, new Scalar(0, 0, 0), 4);&#xA;            return matFrame;&#xA;        }&#xA;        else&#xA;            return  inputFrame.rgba();&#xA;    }&#xA;}&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;p class=wp-block-paragraph&gt;The core of our implementation focuses on the &lt;code&gt;CameraBridgeViewBase.CvCameraViewListener2&lt;/code&gt; interface. To handle the camera feed and process image data, we must implement the following three mandatory methods:&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: java; title: ; notranslate&#34;&gt;public interface CvCameraViewListener2 {&#xA;&#x9;public void onCameraViewStarted(int width, int height);&#xA;&#x9;public void onCameraViewStopped();&#xA;&#x9;public Mat onCameraFrame(CvCameraViewFrame inputFrame);&#xA;};&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;p class=wp-block-paragraph&gt;The naming convention of these methods is quite intuitive. For instance, &lt;code&gt;onCameraViewStarted&lt;/code&gt; is triggered as soon as the camera function is activated. Conversely, when the camera is deactivated or the activity is destroyed, &lt;code&gt;onCameraViewStopped&lt;/code&gt; is invoked to handle the shutdown. Finally, &lt;code&gt;onCameraFrame&lt;/code&gt; is called continuously, frame-by-frame, during the camera’s active state. This entire lifecycle procedure is managed within the &lt;code&gt;MyHelloOpenCVActivity&lt;/code&gt; class.&lt;ul class=wp-block-list&gt;&lt;li&gt;Define the CameraBridgeViewBase Class.&lt;li&gt;Attach the View during the &lt;code&gt;onCreate()&lt;/code&gt; call.&lt;li&gt;Activate the Listener via &lt;code&gt;setCvCameraViewListener()&lt;/code&gt;.&lt;/ul&gt;&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: java; title: ; notranslate&#34;&gt;public class MyHelloOpenCVActivity extends CameraActivity implements CameraBridgeViewBase.CvCameraViewListener2 {&#xA;    &#xA;    private CameraBridgeViewBase mOpenCvCameraView;&#xA;&#xA;    ...&#xA;&#xA;    @Override&#xA;    protected void onCreate(Bundle savedInstanceState) {&#xA;        super.onCreate(savedInstanceState);&#xA;&#xA;        ...&#xA;        mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.camera_hellocv_java_surface_view);&#xA;&#xA;        mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);&#xA;&#xA;        mOpenCvCameraView.setCvCameraViewListener(this);&#xA;    }&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;p class=wp-block-paragraph&gt;The instance of &lt;code&gt;CameraBridgeViewBase&lt;/code&gt; must be strictly managed in synchronization with the lifecycle of &lt;code&gt;MyHelloOpenCVActivity&lt;/code&gt;. Since the camera is a shared hardware resource, failing to pause or release it correctly when the activity moves to the background can lead to memory leaks, app crashes, or the inability for other applications to access the camera.&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: java; title: ; notranslate&#34;&gt;private CameraBridgeViewBase mOpenCvCameraView;&#xA;&#xA;...&#xA;&#xA;&#xA;@Override&#xA;protected void onCreate(Bundle savedInstanceState) {&#xA;&#x9;super.onCreate(savedInstanceState);&#xA;&#xA;&#x9;...&#xA;&#x9;mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.camera_hellocv_java_surface_view);&#xA;}&#xA;&#xA;@Override&#xA;public void onPause()&#xA;{&#xA;&#x9;super.onPause();&#xA;&#x9;if (mOpenCvCameraView != null)&#xA;&#x9;&#x9;mOpenCvCameraView.disableView();&#xA;}&#xA;&#xA;@Override&#xA;public void onResume()&#xA;{&#xA;&#x9;super.onResume();&#xA;&#x9;if (mOpenCvCameraView != null)&#xA;&#x9;&#x9;mOpenCvCameraView.enableView();&#xA;}&#xA;&#xA;@Override&#xA;public void onDestroy() {&#xA;&#x9;super.onDestroy();&#xA;&#x9;if (mOpenCvCameraView != null)&#xA;&#x9;&#x9;mOpenCvCameraView.disableView();&#xA;}&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;h3 class=wp-block-heading&gt;&lt;a name=results&gt;&lt;/a&gt;8.4. Results&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;As the final result of our ‘Hello World’ OpenCV implementation, the GUI demonstrates a key distinction in how data is rendered. While the previous section focused on updating a standard &lt;code&gt;TextView&lt;/code&gt; based on user selection, this final stage utilizes OpenCV to &lt;strong&gt;draw messages directly onto the camera frames&lt;/strong&gt;. By manipulating the image matrix, the application overlays real-time information onto the video stream, showcasing the fundamental power of computer vision GUI processing.&lt;figure class=&#34;wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-5 is-layout-flex wp-block-gallery-is-layout-flex&#34;&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.My-Hello-OpenCV.jpeg&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.My-Hello-OpenCV-1024x640.jpeg decoding=async width=1024 height=640 data-id=142147 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.My-Hello-OpenCV-1024x640.jpeg alt class=wp-image-142147 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.My-Hello-OpenCV-1024x640.jpeg 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.My-Hello-OpenCV-300x188.jpeg 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.My-Hello-OpenCV-768x480.jpeg 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.My-Hello-OpenCV-1536x960.jpeg 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.My-Hello-OpenCV-2048x1280.jpeg 2048w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=640 data-id=142147 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.My-Hello-OpenCV-1024x640.jpeg alt class=wp-image-142147 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.My-Hello-OpenCV-1024x640.jpeg 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.My-Hello-OpenCV-300x188.jpeg 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.My-Hello-OpenCV-768x480.jpeg 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.My-Hello-OpenCV-1536x960.jpeg 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/1.My-Hello-OpenCV-2048x1280.jpeg 2048w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/2.My-Hello-OpenCV.jpeg&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/2.My-Hello-OpenCV-1024x640.jpeg decoding=async width=1024 height=640 data-id=142145 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/2.My-Hello-OpenCV-1024x640.jpeg alt class=wp-image-142145 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/2.My-Hello-OpenCV-1024x640.jpeg 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/2.My-Hello-OpenCV-300x188.jpeg 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/2.My-Hello-OpenCV-768x480.jpeg 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/2.My-Hello-OpenCV-1536x960.jpeg 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/2.My-Hello-OpenCV-2048x1280.jpeg 2048w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=640 data-id=142145 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/2.My-Hello-OpenCV-1024x640.jpeg alt class=wp-image-142145 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/2.My-Hello-OpenCV-1024x640.jpeg 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/2.My-Hello-OpenCV-300x188.jpeg 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/2.My-Hello-OpenCV-768x480.jpeg 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/2.My-Hello-OpenCV-1536x960.jpeg 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/2.My-Hello-OpenCV-2048x1280.jpeg 2048w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/3.My-Hello-OpenCV.jpeg&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/3.My-Hello-OpenCV-1024x640.jpeg decoding=async width=1024 height=640 data-id=142149 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/3.My-Hello-OpenCV-1024x640.jpeg alt class=wp-image-142149 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/3.My-Hello-OpenCV-1024x640.jpeg 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/3.My-Hello-OpenCV-300x188.jpeg 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/3.My-Hello-OpenCV-768x480.jpeg 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/3.My-Hello-OpenCV-1536x960.jpeg 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/3.My-Hello-OpenCV-2048x1280.jpeg 2048w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=640 data-id=142149 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/3.My-Hello-OpenCV-1024x640.jpeg alt class=wp-image-142149 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/3.My-Hello-OpenCV-1024x640.jpeg 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/3.My-Hello-OpenCV-300x188.jpeg 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/3.My-Hello-OpenCV-768x480.jpeg 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/3.My-Hello-OpenCV-1536x960.jpeg 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/3.My-Hello-OpenCV-2048x1280.jpeg 2048w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/4.My-Hello-OpenCV.jpeg&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/4.My-Hello-OpenCV-1024x640.jpeg decoding=async width=1024 height=640 data-id=142146 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/4.My-Hello-OpenCV-1024x640.jpeg alt class=wp-image-142146 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/4.My-Hello-OpenCV-1024x640.jpeg 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/4.My-Hello-OpenCV-300x188.jpeg 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/4.My-Hello-OpenCV-768x480.jpeg 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/4.My-Hello-OpenCV-1536x960.jpeg 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/4.My-Hello-OpenCV-2048x1280.jpeg 2048w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=640 data-id=142146 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/4.My-Hello-OpenCV-1024x640.jpeg alt class=wp-image-142146 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/4.My-Hello-OpenCV-1024x640.jpeg 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/4.My-Hello-OpenCV-300x188.jpeg 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/4.My-Hello-OpenCV-768x480.jpeg 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/4.My-Hello-OpenCV-1536x960.jpeg 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/4.My-Hello-OpenCV-2048x1280.jpeg 2048w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.My-Hello-OpenCV.jpeg&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.My-Hello-OpenCV-1024x640.jpeg decoding=async width=1024 height=640 data-id=142148 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.My-Hello-OpenCV-1024x640.jpeg alt class=wp-image-142148 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.My-Hello-OpenCV-1024x640.jpeg 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.My-Hello-OpenCV-300x188.jpeg 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.My-Hello-OpenCV-768x480.jpeg 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.My-Hello-OpenCV-1536x960.jpeg 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.My-Hello-OpenCV-2048x1280.jpeg 2048w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=640 data-id=142148 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.My-Hello-OpenCV-1024x640.jpeg alt class=wp-image-142148 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.My-Hello-OpenCV-1024x640.jpeg 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.My-Hello-OpenCV-300x188.jpeg 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.My-Hello-OpenCV-768x480.jpeg 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.My-Hello-OpenCV-1536x960.jpeg 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/5.My-Hello-OpenCV-2048x1280.jpeg 2048w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/figure&gt;&lt;p class=wp-block-paragraph&gt;In the next section, we will explore the various samples provided within the &lt;strong&gt;OpenCV Android SDK&lt;/strong&gt;. Our goal is to identify a suitable reference project that can serve as a robust foundation or a functional substitute for our &lt;strong&gt;object inference application&lt;/strong&gt;.&lt;h2 class=wp-block-heading&gt;&lt;a name=object_detector&gt;&lt;/a&gt;9. Object Detector App&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;Since we have already mastered building and deploying the OpenCV SDK samples onto Android devices, we can now evaluate which sample provides the best architecture for our &lt;strong&gt;Object Inference App&lt;/strong&gt;. To ensure a seamless user experience, we have defined two key functional requirements:&lt;ol start=1 class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;Model Selection via Dynamic Menu:&lt;/strong&gt; The application must feature a fixed menu with a drop-down list, allowing users to switch between different inference models (e.g., YOLO, Mask R-CNN, or MobileNet) on the fly.&lt;li&gt;&lt;strong&gt;Instantaneous Inference:&lt;/strong&gt; Object detection must trigger immediately upon model selection, ensuring that the &lt;code&gt;onCameraFrame&lt;/code&gt; logic begins processing the live feed using the newly loaded weights without requiring an app restart.&lt;/ol&gt;&lt;h3 class=wp-block-heading&gt;&lt;a name=camera_calibration&gt;&lt;/a&gt;9.1. Camera Calibration Overview&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;The basic is done—how to build and run a simple app and a simple OpenCV app. It means we are now ready to make an app for object detection on a real Android device.&lt;p class=wp-block-paragraph&gt;But at some point, we doubt that we must start from scratch—designing and building sources, layouts, and resources. This would spend too much time focusing on supplementary parts that are not even part of object detection.&lt;p class=wp-block-paragraph&gt;Therefore, we are going to follow the simple way: building our app by customizing the samples provided by OpenCV that are already proven in practice. These are the conditions that meet our requirements:&lt;ul class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;Display&lt;/strong&gt; bounding boxes when objects are detected.&lt;li&gt;&lt;strong&gt;Select&lt;/strong&gt; any model from the menu.&lt;li&gt;&lt;strong&gt;Load&lt;/strong&gt; a model into memory.&lt;li&gt;&lt;strong&gt;Render&lt;/strong&gt; frame by frame if the camera is ready.&lt;li&gt;&lt;strong&gt;Recognize&lt;/strong&gt; objects in the image source of the frame.&lt;/ul&gt;&lt;h4 class=wp-block-heading&gt;1. Class Diagram and Workflow&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;Our object detection diagram will be similar to the &lt;strong&gt;camera-calibration&lt;/strong&gt; class diagram. In the case of camera calibration, the steps are:&lt;ol start=1 class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;Render&lt;/strong&gt; an image source frame-by-frame when the camera is ready.&lt;li&gt;&lt;strong&gt;Run&lt;/strong&gt; calibration on that image source continuously at the same time.&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/camera-calibration-1.png&gt;&lt;/a&gt;&lt;/ol&gt;&lt;figure class=&#34;wp-block-image size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/camera-calibration-1.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/camera-calibration-1.png decoding=async width=975 height=505 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/camera-calibration-1.png alt class=wp-image-141926 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/camera-calibration-1.png 975w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/camera-calibration-1-300x155.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/camera-calibration-1-768x398.png 768w&#34; data-sizes=&#34;(max-width: 975px) 100vw, 975px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=975 height=505 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/camera-calibration-1.png alt class=wp-image-141926 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/camera-calibration-1.png 975w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/camera-calibration-1-300x155.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/camera-calibration-1-768x398.png 768w&#34; sizes=&#34;(max-width: 975px) 100vw, 975px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;p class=wp-block-paragraph&gt;Based on this logic, we expect the calibration sample to cover our required functionalities:&lt;ul class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;Renders&lt;/strong&gt; the image source when the camera is available.&lt;li&gt;Allows the user to &lt;strong&gt;select a model&lt;/strong&gt; from the available options.&lt;li&gt;Triggers &lt;strong&gt;different behaviors&lt;/strong&gt; depending on the selected option.&lt;li&gt;&lt;strong&gt;Detects objects&lt;/strong&gt; in the image source using the selected inference model.&lt;/ul&gt;&lt;h3 class=wp-block-heading&gt;&lt;a name=my_object_detector&gt;&lt;/a&gt;9.2 My Object Detecor&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;Our object detector, named &lt;strong&gt;&lt;code&gt;my-object-detector&lt;/code&gt;&lt;/strong&gt;, is designed to detect objects by separating them from the background and labeling the upper part of each detected object. This implementation is based on the source code of the &lt;code&gt;camera-calibration&lt;/code&gt; sample.&lt;h4 class=wp-block-heading&gt;1. Initial Version Setup&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;To begin, we need to isolate our project within the OpenCV SDK environment. Navigate to the samples folder: &lt;code&gt;C:\DEV\Works\opencv-object-detector\OpenCV-android-sdk\samples&lt;/code&gt;&lt;p class=wp-block-paragraph&gt;In Android Studio, open the &lt;code&gt;settings.gradle&lt;/code&gt; file from the Project Files view. To focus exclusively on our app, disable all other sample projects by commenting out their &lt;code&gt;include&lt;/code&gt; tags and add our project as follows:&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: groovy; title: ; notranslate&#34;&gt;rootProject.name = &amp;#39;opencv_samples&amp;#39;&#xA;gradle.ext {&#xA;    // possible options: &amp;#39;maven_central&amp;#39;, &amp;#39;maven_local&amp;#39;, &amp;#39;sdk_path&amp;#39;&#xA;    opencv_source = &amp;#39;sdk_path&amp;#39;&#xA;}&#xA;&#xA;if (gradle.opencv_source == &amp;#39;maven_local&amp;#39;) {&#xA;    gradle.ext {&#xA;        opencv_maven_path = &amp;#39;&amp;lt;path_to_maven_repo&amp;gt;&amp;#39;&#xA;    }&#xA;}&#xA;&#xA;if (gradle.opencv_source == &amp;#39;sdk_path&amp;#39;) {&#xA;    def opencvsdk = &amp;#39;../&amp;#39;&#xA;    //def opencvsdk=&amp;#39;/&amp;lt;path to OpenCV-android-sdk&amp;gt;&amp;#39;&#xA;    //println opencvsdk&#xA;    include &amp;#39;:opencv&amp;#39;&#xA;    project(&amp;#39;:opencv&amp;#39;).projectDir = new File(opencvsdk + &amp;#39;/sdk&amp;#39;)&#xA;}&#xA;include &amp;#39;:my-object-detector&amp;#39;&#xA;//include &amp;#39;:15-puzzle&amp;#39;&#xA;//include &amp;#39;:face-detection&amp;#39;&#xA;//include &amp;#39;:qr-detection&amp;#39;&#xA;//include &amp;#39;:image-manipulations&amp;#39;&#xA;//include &amp;#39;:camera-calibration&amp;#39;&#xA;//include &amp;#39;:color-blob-detection&amp;#39;&#xA;//include &amp;#39;:mobilenet-objdetect&amp;#39;&#xA;//include &amp;#39;:video-recorder&amp;#39;&#xA;//include &amp;#39;:tutorial-1-camerapreview&amp;#39;&#xA;//include &amp;#39;:tutorial-2-mixedprocessing&amp;#39;&#xA;//include &amp;#39;:tutorial-3-cameracontrol&amp;#39;&#xA;//include &amp;#39;:tutorial-4-opencl&amp;#39;&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;figure class=&#34;wp-block-image size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/03/13.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/13.png decoding=async width=773 height=595 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/13.png alt class=wp-image-141923 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/13.png 773w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/13-300x231.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/13-768x591.png 768w&#34; data-sizes=&#34;(max-width: 773px) 100vw, 773px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=773 height=595 src=https://www.javacodegeeks.com/wp-content/uploads/2026/03/13.png alt class=wp-image-141923 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/03/13.png 773w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/13-300x231.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/03/13-768x591.png 768w&#34; sizes=&#34;(max-width: 773px) 100vw, 773px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;h4 class=wp-block-heading&gt;2. Project Copy &amp;amp; Strategy Pattern&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;Next, copy the &lt;strong&gt;camera-calibration&lt;/strong&gt; project to create &lt;strong&gt;my-object-detector&lt;/strong&gt;.&lt;p class=wp-block-paragraph&gt;Our custom object detector implements the &lt;strong&gt;Strategy Pattern&lt;/strong&gt;. This helps the object detection via &lt;code&gt;OnCameraFrameRender&lt;/code&gt;, which is implemented by the &lt;code&gt;FrameRender&lt;/code&gt; abstract class.&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: java; title: ; notranslate&#34;&gt;public class OnCameraFrameRender {&#xA;    private final FrameRender mFrameRender;&#xA;    public OnCameraFrameRender(FrameRender frameRender) {&#xA;        mFrameRender = frameRender;&#xA;    }&#xA;    public Mat render(CvCameraViewFrame inputFrame) {&#xA;        return mFrameRender.render(inputFrame);&#xA;    }&#xA;}&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;h4 class=wp-block-heading&gt;3. Executing the Strategy&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;The system calls the &lt;strong&gt;&lt;code&gt;render&lt;/code&gt;&lt;/strong&gt; method of the concrete strategy class, passing the &lt;code&gt;CvCameraViewFrame&lt;/code&gt; provided by OpenCV as the camera input.&lt;p class=wp-block-paragraph&gt;For example, we can implement a &lt;code&gt;Yolov3FrameRender&lt;/code&gt; class. Inside its &lt;code&gt;render&lt;/code&gt; method, it utilizes a &lt;code&gt;Yolov3Detector&lt;/code&gt; class to perform object inference using the &lt;code&gt;CvCameraViewFrame&lt;/code&gt; object received from the camera input.&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: java; title: ; notranslate&#34;&gt;public Mat render(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {&#xA;&#x9;Mat bgrFrame = inputFrame.rgba();&#xA;&#xA;&#x9;Imgproc.cvtColor(bgrFrame, bgrFrame, Imgproc.COLOR_RGBA2BGR);&#xA;&#x9;Yolov3Detector.getInstance().setDetectorNet(mDetectorData);&#xA;&#xA;&#x9;return Yolov3Detector.getInstance().detectObjectByYolov3(bgrFrame);&#xA;}&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;h4 class=wp-block-heading&gt;4. Class Diagram&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;&lt;strong&gt;Inspired by the calibration app&lt;/strong&gt;, this class diagram illustrates the architecture of our mobile detector. &lt;strong&gt;The system invokes the appropriate object inference model by calling specific renderers based on user options.&lt;/strong&gt; Each renderer then executes the inference model in memory and draws bounding boxes directly onto the main activity screen.&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/05/image-3.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/image-3-1024x519.png decoding=async width=1024 height=519 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/image-3-1024x519.png alt class=wp-image-143628 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/image-3-1024x519.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/image-3-300x152.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/image-3-768x390.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/image-3.png 1315w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=519 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/image-3-1024x519.png alt class=wp-image-143628 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/image-3-1024x519.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/image-3-300x152.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/image-3-768x390.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/image-3.png 1315w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;p class=wp-block-paragraph&gt;My concept of the Object Detector is as follows:&lt;ul class=wp-block-list&gt;&lt;li&gt;&lt;code&gt;ObjectDetectionActivity&lt;/code&gt; extends &lt;code&gt;CameraActivity&lt;/code&gt; and manages the user interaction GUI.&lt;li&gt;&lt;strong&gt;The application instantiates the render classes&lt;/strong&gt;, which stand ready within &lt;code&gt;OnCameraFrameRender&lt;/code&gt;.&lt;li&gt;This render loop receives &lt;code&gt;DetectorNetData&lt;/code&gt; via its constructor, which in turn initializes and saves the detector classes using &lt;code&gt;DnnModelRepository&lt;/code&gt;.&lt;li&gt;Whenever the &lt;code&gt;FrameRender&lt;/code&gt; class invokes &lt;code&gt;render()&lt;/code&gt;, the system seamlessly matches the user’s selected model with the proper detector class to execute object detection.&lt;/ul&gt;&lt;h4 class=wp-block-heading&gt;5. ObjectDetectionActivity&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;&lt;code&gt;ObjectDetectionActivity&lt;/code&gt; serves as our main activity, handling user interactions and ultimately rendering the bounding boxes predicted by the object inference model. Consequently, the skeleton of this class must implement the &lt;code&gt;CvCameraViewListener2&lt;/code&gt; interface, as shown below:&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: java; title: ; notranslate&#34;&gt;public class ObjectDetectionActivity extends CameraActivity implements CvCameraViewListener2 {&#xA;    @Override&#xA;    public void onCreate(Bundle savedInstanceState) {&#xA;   &#xA;    }&#xA;&#xA;    @Override&#xA;    public void onPause()&#xA;    {&#xA;    }&#xA;&#xA;    @Override&#xA;    public void onResume()&#xA;    {&#xA;    }&#xA;&#xA;    @Override&#xA;    protected List&amp;lt;? extends CameraBridgeViewBase&amp;gt; getCameraViewList() {&#xA;        return Collections.singletonList(mOpenCvCameraView);&#xA;    }&#xA;&#xA;    public void onDestroy() {&#xA;        &#xA;    }&#xA;&#xA;    @Override&#xA;    public boolean onCreateOptionsMenu(Menu menu) {&#xA;        return true;&#xA;    }&#xA;&#xA;    @Override&#xA;    public boolean onPrepareOptionsMenu (Menu menu) {&#xA;        return true;&#xA;    }&#xA;&#xA;    @Override&#xA;    public boolean onOptionsItemSelected(MenuItem item) {&#xA;        &#xA;        return true;&#xA;    }&#xA;&#xA;    @Override&#xA;    public void onCameraViewStarted(int width, int height) {&#xA;    }&#xA;&#xA;    @Override&#xA;    public void onCameraViewStopped() {&#xA;    }&#xA;&#xA;    @Override&#xA;    public Mat onCameraFrame(CvCameraViewFrame inputFrame) {&#xA;    }&#xA;&#xA;    @Override&#xA;    public boolean onTouch(View v, MotionEvent event) {&#xA;        return false;&#xA;    }&#xA;}&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;p class=wp-block-paragraph&gt;Our &lt;code&gt;ObjectDetectionActivity&lt;/code&gt; class must implement the three methods of the &lt;code&gt;CvCameraViewListener2&lt;/code&gt; interface. These methods are triggered by callbacks from the &lt;code&gt;CameraActivity&lt;/code&gt; class after it has internally handled essential pre-processing tasks, such as:&lt;p class=wp-block-paragraph&gt;&lt;strong&gt;Converting Image Sources&lt;/strong&gt;: Transforming the raw camera feed into a &lt;code&gt;CvCameraViewFrame&lt;/code&gt; object for OpenCV processing.&lt;ul class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;Requesting Permissions&lt;/strong&gt;: Ensuring the app has the necessary camera access.&lt;li&gt;&lt;strong&gt;Preparing Camera Conditions&lt;/strong&gt;: Setting up the hardware, resolution, and focus.&lt;/ul&gt;&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: java; title: ; notranslate&#34;&gt;public interface CvCameraViewListener2 {&#xA;&#x9;/**&#xA;&#x9; * This method is invoked when camera preview has started. After this method is invoked&#xA;&#x9; * the frames will start to be delivered to client via the onCameraFrame() callback.&#xA;&#x9; * @param width -  the width of the frames that will be delivered&#xA;&#x9; * @param height - the height of the frames that will be delivered&#xA;&#x9; */&#xA;&#x9;public void onCameraViewStarted(int width, int height);&#xA;&#xA;&#x9;/**&#xA;&#x9; * This method is invoked when camera preview has been stopped for some reason.&#xA;&#x9; * No frames will be delivered via onCameraFrame() callback after this method is called.&#xA;&#x9; */&#xA;&#x9;public void onCameraViewStopped();&#xA;&#xA;&#x9;/**&#xA;&#x9; * This method is invoked when delivery of the frame needs to be done.&#xA;&#x9; * The returned values - is a modified frame which needs to be displayed on the screen.&#xA;&#x9; * TODO: pass the parameters specifying the format of the frame (BPP, YUV or RGB and etc)&#xA;&#x9; */&#xA;&#x9;public Mat onCameraFrame(CvCameraViewFrame inputFrame);&#xA;};&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;h3 class=wp-block-heading&gt;&lt;a name=detection_process&gt;&lt;/a&gt;9.3. Object Detection Process&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;The object detection workflow in our application follows a structured sequence to ensure real-time performance:&lt;p class=wp-block-paragraph&gt;&lt;strong&gt;Result Rendering:&lt;/strong&gt; The detected objects (bounding boxes and labels) are rendered on the screen.app, the CameraBridgeViewBase class of OpenCV can do for us by just calling enableView().&lt;ul class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;Camera Activation:&lt;/strong&gt; The camera view must be active as soon as the app starts.&lt;li&gt;&lt;strong&gt;Model Selection:&lt;/strong&gt; The user chooses a specific object detection model from the menu&lt;li&gt;&lt;strong&gt;Memory Loading:&lt;/strong&gt; The selected model is loaded into memory to prepare for inference.&lt;li&gt;&lt;strong&gt;Real-time Inference:&lt;/strong&gt; Object inference is executed frame-by-frame using the loaded model.&lt;/ul&gt;&lt;p class=wp-block-paragraph&gt;To ensure the camera activates automatically whenever the app runs, we utilize the &lt;code&gt;CameraBridgeViewBase&lt;/code&gt; class from the OpenCV SDK. By simply calling &lt;code&gt;enableView()&lt;/code&gt;, the class handles the underlying camera connection and start-up process for us.&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: java; title: ; notranslate&#34;&gt;@Override&#xA;public void onResume()&#xA;{&#xA;&#x9;super.onResume();&#xA;&#x9;if (mOpenCvCameraView != null) {&#xA;&#x9;&#x9;mOpenCvCameraView.enableView();&#xA;&#x9;}&#xA;}&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;p class=wp-block-paragraph&gt;When a user selects a specific object detection model from the menu, the application executes a two-step procedure to ensure the inference engine and the UI are perfectly synchronized:&lt;h4 class=wp-block-heading&gt;1. Initializing the Inference Model&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;First, the application identifies the chosen model (e.g., YOLO, SSD, or MobileNet) and loads the corresponding network configuration and weight files into memory. This step initializes the &lt;strong&gt;Inference Engine&lt;/strong&gt; (such as OpenCV’s &lt;code&gt;dnn&lt;/code&gt; module).&lt;h4 class=wp-block-heading&gt;2. Choosing the Right Renderer&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;Once the model is loaded, the application must switch to the appropriate &lt;strong&gt;Renderer&lt;/strong&gt; that fits the model’s specific output format. Since different models return detection data (bounding boxes, confidence scores, etc.) in different structures, a dedicated renderer (e.g., &lt;code&gt;Yolov3FrameRender&lt;/code&gt;) is required to correctly interpret and draw the results on the screen.&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: java; title: ; notranslate&#34;&gt;@Override&#xA;public boolean onOptionsItemSelected(MenuItem item) {&#xA;&#x9;boolean retBool = false;&#xA;&#xA;&#x9;mObjDetectorNet.preDetectorProcess(this, DetectorNetData.CvDetectorType.METHOD_NORMAL);&#xA;&#x9;mOnCameraFrameRender = new OnCameraFrameRender(new PreviewFrameRender());&#xA;&#x9;int id = item.getItemId();&#xA;&#x9;if(id == R.id.normal)&#xA;&#x9;{&#xA;&#x9;&#x9;... Do some normal work&#xA;&#x9;&#x9;item.setChecked(true);&#xA;&#x9;&#x9;retBool = true;&#xA;&#x9;}&#xA;&#x9;else if(id == R.id.maskrcnn)&#xA;&#x9;{&#xA;&#x9;&#x9;... Do some rcnn model work&#xA;&#x9;&#x9;item.setChecked(true);&#xA;&#x9;&#x9;retBool = true;&#xA;&#x9;}&#xA;&#x9;else if(id == R.id.yolov3)&#xA;&#x9;{&#xA;&#x9;&#x9;... Do some yolo model work&#xA;&#x9;&#x9;item.setChecked(true);&#xA;&#x9;&#x9;retBool = true;&#xA;&#x9;}&#xA;&#x9;else if(id == R.id.yolov3_tiny)&#xA;&#x9;{&#xA;&#x9;&#x9;... Do some yolo model work&#xA;&#xA;&#x9;&#x9;item.setChecked(true);&#xA;&#x9;&#x9;retBool = true;&#xA;&#x9;}&#xA;&#x9;else if(id == R.id.yolov7_tiny)&#xA;&#x9;{&#xA;&#x9;&#x9;... Do some yolo model work&#xA;&#xA;&#x9;&#x9;item.setChecked(true);&#xA;&#x9;&#x9;retBool = true;&#xA;&#x9;}&#xA;&#x9;else if(id == R.id.mobile_net)&#xA;&#x9;{&#xA;&#x9;&#x9;... Do some mobile net model work&#xA;&#xA;&#x9;&#x9;item.setChecked(true);&#xA;&#x9;&#x9;retBool = true;&#xA;&#x9;}&#xA;&#x9;else&#xA;&#x9;{&#xA;&#x9;&#x9;retBool = super.onOptionsItemSelected(item);&#xA;&#x9;}&#xA;&#x9;return retBool;&#xA;}&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;p class=wp-block-paragraph&gt;Below is the mapping between each &lt;strong&gt;Render Class&lt;/strong&gt; (Strategy) and its corresponding &lt;strong&gt;Model Files&lt;/strong&gt; (Inference) as used in the selection process:&lt;figure class=wp-block-table&gt;&lt;table class=has-fixed-layout&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Option (Menu)&lt;td&gt;Render Class (Strategy)&lt;td&gt;Model Files (Configuration / Weights)&lt;tr&gt;&lt;td&gt;Mask-RCNN&lt;td&gt;MaskRCNNDetector&lt;td&gt;mask_rcnn_inception_v2_coco_2018_01_28.pbtxt / frozen_inference_graph.pb&lt;tr&gt;&lt;td&gt;MobileNet-SSD v3&lt;td&gt;MobileNetSSDDetector&lt;td&gt;ssd_mobilenet_v3_large_coco_2020_01_14.pbtxt / frozen_inference_graph_ssd.pb&lt;tr&gt;&lt;td&gt;Yolo v3&lt;td&gt;Yolov3Detector&lt;td&gt;yolov3.cfg /&lt;br&gt;yolov3.weights&lt;br&gt;yolov3-tiny.weights&lt;tr&gt;&lt;td&gt;Yolo v7 tiny&lt;td&gt;Yolov7Detector&lt;td&gt;yolov7.cfg /&lt;br&gt;yolov7-tiny.weights&lt;/table&gt;&lt;/figure&gt;&lt;h4 class=wp-block-heading&gt;3. Loading the Model&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;Loading the model into memory is the most critical priority in our inference application. However, in the Android ecosystem, accessing the file system is restricted by the &lt;strong&gt;“Sandbox”&lt;/strong&gt; security model. This means a user app is prohibited from directly accessing file paths without explicit permissions or proper context.&lt;p class=wp-block-paragraph&gt;To load our model in the simplest yet safest way, we will package the model files within the &lt;strong&gt;&lt;code&gt;assets&lt;/code&gt; folder&lt;/strong&gt;. This folder is specifically designed for raw data and resources that need to be bundled with the application package (APK).&lt;h4 class=wp-block-heading&gt;4. Why use the Assets folder?&lt;/h4&gt;&lt;ul class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;Access:&lt;/strong&gt; We can use the &lt;code&gt;AssetManager&lt;/code&gt; to read these files and copy them to the app’s internal cache directory, providing a valid file path for the OpenCV &lt;code&gt;dnn&lt;/code&gt; module.&lt;li&gt;&lt;strong&gt;Security:&lt;/strong&gt; Files in &lt;code&gt;assets&lt;/code&gt; are private to the application and do not require external storage permissions.&lt;li&gt;&lt;strong&gt;Convenience:&lt;/strong&gt; The model files (e.g., &lt;code&gt;.cfg&lt;/code&gt;, &lt;code&gt;.weights&lt;/code&gt;, &lt;code&gt;.pb&lt;/code&gt;) are bundled together during the build process, ensuring they are always available when the app is installed.&lt;/ul&gt;&lt;h3 class=wp-block-heading&gt;&lt;a name=role_detectornetdata&gt;&lt;/a&gt;9.4. The Role of DetectorNetData&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;The &lt;code&gt;DetectorNetData&lt;/code&gt; class is responsible for managing the model files required for inference. It handles the transition from static assets to accessible runtime files:&lt;ol start=1 class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;Reading from Assets&lt;/strong&gt;: It accesses the raw model files (e.g., configurations and weights) stored within the application’s &lt;code&gt;assets&lt;/code&gt; folder.&lt;li&gt;&lt;strong&gt;Writing to Internal Storage&lt;/strong&gt;: Since the OpenCV DNN module requires a filesystem path to load models, &lt;code&gt;DetectorNetData&lt;/code&gt; writes these files to a private directory that our detector app can safely access at runtime.&lt;/ol&gt;&lt;p class=wp-block-paragraph&gt;By utilizing this class, we ensure that the model files are securely extracted and ready for the inference engine without violating Android’s sandbox security policies.&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: java; title: ; notranslate&#34;&gt;public void preDetectorProcess(final Context ctx, final CvDetectorType detectorType) {&#xA;&#x9;setDetectorType(detectorType);&#xA;&#xA;&#x9;if(detectorType == CvDetectorType.METHOD_MRCNN)&#xA;&#x9;{&#xA;&#x9;&#x9;final String cfgFile = getMRcnnConfig(ctx);&#xA;&#x9;&#x9;final String modelFile = getMRcnnModel(ctx);&#xA;&#xA;&#x9;&#x9;boolean isSetupCompleted = true;&#xA;&#x9;&#x9;if(modelFile == null)&#xA;&#x9;&#x9;{&#xA;&#x9;&#x9;&#x9;Log.i(TAG, &amp;#34;Config file path not found!!!!&amp;#34;);&#xA;&#x9;&#x9;&#x9;isSetupCompleted = false;&#xA;&#x9;&#x9;}&#xA;&#xA;&#x9;&#x9;if(cfgFile == null)&#xA;&#x9;&#x9;{&#xA;&#x9;&#x9;&#x9;Log.i(TAG, &amp;#34;weightFile file path not found!!!!&amp;#34;);&#xA;&#x9;&#x9;&#x9;isSetupCompleted = false;&#xA;&#x9;&#x9;}&#xA;&#xA;&#x9;&#x9;if(isSetupCompleted)&#xA;&#x9;&#x9;{&#xA;&#x9;&#x9;&#x9;DnnModelRepository.getInstance().unloadModel(detectorType.toString());&#xA;&#x9;&#x9;&#x9;setDnnNet(DnnModelRepository.getInstance().loadModel(detectorType, modelFile, cfgFile));&#xA;&#x9;&#x9;}&#xA;&#x9;}&#xA;&#x9;else if(detectorType == CvDetectorType.METHOD_YOLOV3)&#xA;&#x9;{&#xA;&#x9;&#x9;final String cfgFile = getYolov3Config(ctx);&#xA;&#x9;&#x9;final String weightFile = getYolov3Weight(ctx);&#xA;&#x9;&#x9;boolean isSetupCompleted = true;&#xA;&#xA;&#x9;&#x9;if(cfgFile == null)&#xA;&#x9;&#x9;{&#xA;&#x9;&#x9;&#x9;Log.i(TAG, &amp;#34;Config file path not found!!!!&amp;#34;);&#xA;&#x9;&#x9;&#x9;isSetupCompleted = false;&#xA;&#x9;&#x9;}&#xA;&#xA;&#x9;&#x9;if(weightFile == null)&#xA;&#x9;&#x9;{&#xA;&#x9;&#x9;&#x9;Log.i(TAG, &amp;#34;weightFile file path not found!!!!&amp;#34;);&#xA;&#x9;&#x9;&#x9;isSetupCompleted = false;&#xA;&#x9;&#x9;}&#xA;&#xA;&#x9;&#x9;if(isSetupCompleted)&#xA;&#x9;&#x9;{&#xA;&#x9;&#x9;&#x9;DnnModelRepository.getInstance().unloadModel(detectorType.toString());&#xA;&#x9;&#x9;&#x9;setDnnNet(DnnModelRepository.getInstance().loadModel(detectorType, weightFile, cfgFile));&#xA;&#x9;&#x9;}&#xA;&#xA;&#x9;}&#xA;&#x9;else if(detectorType == CvDetectorType.METHOD_YOLOV3_TINY)&#xA;&#x9;{&#xA;&#x9;&#x9;final String cfgFile = getYolov3TinyConfig(ctx);&#xA;&#x9;&#x9;final String weightFile = getYolov3TinyWeight(ctx);&#xA;&#x9;&#x9;boolean isSetupCompleted = true;&#xA;&#xA;&#x9;&#x9;if(cfgFile == null)&#xA;&#x9;&#x9;{&#xA;&#x9;&#x9;&#x9;Log.i(TAG, &amp;#34;Config file path not found!!!!&amp;#34;);&#xA;&#x9;&#x9;&#x9;isSetupCompleted = false;&#xA;&#x9;&#x9;}&#xA;&#xA;&#x9;&#x9;if(weightFile == null)&#xA;&#x9;&#x9;{&#xA;&#x9;&#x9;&#x9;Log.i(TAG, &amp;#34;weightFile file path not found!!!!&amp;#34;);&#xA;&#x9;&#x9;&#x9;isSetupCompleted = false;&#xA;&#x9;&#x9;}&#xA;&#xA;&#x9;&#x9;if(isSetupCompleted)&#xA;&#x9;&#x9;{&#xA;&#x9;&#x9;&#x9;DnnModelRepository.getInstance().unloadModel(detectorType.toString());&#xA;&#x9;&#x9;&#x9;setDnnNet(DnnModelRepository.getInstance().loadModel(detectorType, weightFile, cfgFile));&#xA;&#x9;&#x9;}&#xA;&#xA;&#x9;}&#xA;&#x9;else if(detectorType == CvDetectorType.METHOD_YOLOV7_TINY)&#xA;&#x9;{&#xA;&#x9;&#x9;final String cfgFile = getYolov7TinyConfig(ctx);&#xA;&#x9;&#x9;final String weightFile = getYolov7TinyWeight(ctx);&#xA;&#x9;&#x9;boolean isSetupCompleted = true;&#xA;&#xA;&#x9;&#x9;if(cfgFile == null)&#xA;&#x9;&#x9;{&#xA;&#x9;&#x9;&#x9;Log.i(TAG, &amp;#34;Config file path not found!!!!&amp;#34;);&#xA;&#x9;&#x9;&#x9;isSetupCompleted = false;&#xA;&#x9;&#x9;}&#xA;&#xA;&#x9;&#x9;if(weightFile == null)&#xA;&#x9;&#x9;{&#xA;&#x9;&#x9;&#x9;Log.i(TAG, &amp;#34;weightFile file path not found!!!!&amp;#34;);&#xA;&#x9;&#x9;&#x9;isSetupCompleted = false;&#xA;&#x9;&#x9;}&#xA;&#xA;&#x9;&#x9;if(isSetupCompleted)&#xA;&#x9;&#x9;{&#xA;&#x9;&#x9;&#x9;DnnModelRepository.getInstance().unloadModel(detectorType.toString());&#xA;&#x9;&#x9;&#x9;setDnnNet(DnnModelRepository.getInstance().loadModel(detectorType, weightFile, cfgFile));&#xA;&#x9;&#x9;}&#xA;&#xA;&#x9;}&#xA;&#x9;else if(detectorType == CvDetectorType.METHOD_MOBNET)&#xA;&#x9;{&#xA;&#x9;&#x9;final String cfgFile = getMBNetConfig(ctx);&#xA;&#x9;&#x9;final String modelFile = getMBNetModel(ctx);&#xA;&#xA;&#x9;&#x9;boolean isSetupCompleted = true;&#xA;&#x9;&#x9;if(modelFile == null)&#xA;&#x9;&#x9;{&#xA;&#x9;&#x9;&#x9;Log.i(TAG, &amp;#34;Config file path not found!!!!&amp;#34;);&#xA;&#x9;&#x9;&#x9;isSetupCompleted = false;&#xA;&#x9;&#x9;}&#xA;&#xA;&#x9;&#x9;if(cfgFile == null)&#xA;&#x9;&#x9;{&#xA;&#x9;&#x9;&#x9;Log.i(TAG, &amp;#34;weightFile file path not found!!!!&amp;#34;);&#xA;&#x9;&#x9;&#x9;isSetupCompleted = false;&#xA;&#x9;&#x9;}&#xA;&#xA;&#x9;&#x9;if(isSetupCompleted)&#xA;&#x9;&#x9;{&#xA;&#x9;&#x9;&#x9;DnnModelRepository.getInstance().unloadModel(detectorType.toString());&#xA;&#x9;&#x9;&#x9;setDnnNet(DnnModelRepository.getInstance().loadModel(detectorType, modelFile, cfgFile));&#xA;&#x9;&#x9;}&#xA;&#x9;}&#xA;&#x9;else if(detectorType == CvDetectorType.METHOD_NORMAL)&#xA;&#x9;{&#xA;&#x9;&#x9;DnnModelRepository.getInstance().clearAll();&#xA;&#x9;&#x9;return;&#xA;&#x9;}&#xA;&#x9;else if(detectorType == CvDetectorType.METHOD_UNKNWON)&#xA;&#x9;{&#xA;&#x9;&#x9;DnnModelRepository.getInstance().clearAll();&#xA;&#x9;&#x9;return;&#xA;&#x9;}&#xA;&#xA;&#x9;if(dnnNet == null) return;&#xA;&#xA;&#x9;setLabel(ctx, detectorType);&#xA;}&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;h3 class=wp-block-heading&gt;&lt;a name=managing_model&gt;&lt;/a&gt;9.5. Managing Model Life Cycle&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;The &lt;strong&gt;&lt;code&gt;DnnModelRepository&lt;/code&gt;&lt;/strong&gt; class acts as a central hub for loading and unloading inference models. It relies on the following logic to ensure the model files are ready for the OpenCV DNN engine:&lt;h4 class=wp-block-heading&gt;1. The &lt;code&gt;getSafeModelAssetPath()&lt;/code&gt; Method&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;This is the core method that bridges the gap between the &lt;code&gt;assets&lt;/code&gt; folder and the Android file system. Its execution flow is as follows:&lt;ol start=1 class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;Check Existence&lt;/strong&gt;: It first checks if the model files already exist in the app’s local sandbox storage.&lt;li&gt;&lt;strong&gt;Conditional Copying&lt;/strong&gt;: If the files are missing, it reads them from the &lt;strong&gt;&lt;code&gt;assets&lt;/code&gt;&lt;/strong&gt; folder and copies them to the internal storage.&lt;li&gt;Target Storage (&lt;code&gt;getFilesDir()&lt;/code&gt;): It uses the &lt;code&gt;getFilesDir()&lt;/code&gt; method of the &lt;code&gt;Context&lt;/code&gt; class. This points to the app’s &lt;strong&gt;internal storage&lt;/strong&gt;, which is:&lt;ul class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;Secure&lt;/strong&gt;: Protected by the Android Sandbox.&lt;li&gt;&lt;strong&gt;Permission-Free&lt;/strong&gt;: Does not require &lt;code&gt;READ/WRITE_EXTERNAL_STORAGE&lt;/code&gt; permissions.&lt;/ul&gt;&lt;li&gt;&lt;strong&gt;Path Return&lt;/strong&gt;: Once the copy is verified, it returns the absolute path of the file, allowing the &lt;code&gt;Dnn&lt;/code&gt; module to load the model successfully.&lt;/ol&gt;&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: java; title: ; notranslate&#34;&gt;private String getSafeModelAssetPath(Context context, String fileName) {&#xA;&#x9;// 1. File object that is saved to the internal storage(no need to gain security permission)&#xA;&#x9;File destFile = new File(context.getFilesDir(), fileName);&#xA;&#xA;&#x9;// 2. It returns its path immediately, if the file is already copied.&#xA;&#x9;if (destFile.exists()) {&#xA;&#x9;&#x9;Log.d(&amp;#34;OpenCV_Model&amp;#34;, &amp;#34;The model is already existed.[&amp;#34; + fileName + &amp;#34;]&amp;#34;);&#xA;&#x9;&#x9;return destFile.getAbsolutePath();&#xA;&#x9;}&#xA;&#xA;&#x9;// 3. It starts to copy from assets directory to the internal storage.&#xA;&#x9;try (InputStream is = context.getAssets().open(fileName);&#xA;&#x9;&#x9; FileOutputStream os = new FileOutputStream(destFile)) {&#xA;&#xA;&#xA;&#x9;&#x9;byte[] buffer = new byte[1024 * 16]; // 16KB Buffer&#xA;&#x9;&#x9;int length;&#xA;&#x9;&#x9;int size = 0;&#xA;&#x9;&#x9;while ((length = is.read(buffer)) &amp;gt; 0) {&#xA;&#x9;&#x9;&#x9;os.write(buffer, 0, length);&#xA;&#x9;&#x9;&#x9;size += length;&#xA;&#x9;&#x9;}&#xA;&#xA;&#x9;&#x9;Log.d(&amp;#34;OpenCV_Model&amp;#34;, String.format(&amp;#34;Model size[%d] Path[%s] &amp;#34;, size, destFile.getAbsolutePath()));&#xA;&#x9;&#x9;return destFile.getAbsolutePath();&#xA;&#xA;&#x9;} catch (IOException e) {&#xA;&#x9;&#x9;Log.e(&amp;#34;OpenCV_Model&amp;#34;, &amp;#34;2.Error while copying: &amp;#34; + e.getMessage());&#xA;&#x9;&#x9;return null;&#xA;&#x9;}&#xA;}&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;h3 class=wp-block-heading&gt;&lt;a name=dnnModelRepository&gt;&lt;/a&gt;9.6. DnnModelRepository&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;The &lt;code&gt;DnnModelRepository&lt;/code&gt; is implemented as a Singleton class to ensure efficient memory management and centralized access to inference models. Instead of reloading heavy models repeatedly, it maintains and reuses &lt;strong&gt;&lt;code&gt;Net&lt;/code&gt;&lt;/strong&gt; objects throughout the application’s lifecycle.&lt;h4 class=wp-block-heading&gt;1. Key Responsibility: Object Reuse&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;By storing the loaded &lt;code&gt;Net&lt;/code&gt; objects in internal storage (memory), the repository avoids the overhead of reading from the disk every time a frame needs to be processed. This is crucial for maintaining a high FPS in our real-time object detection app.&lt;h4 class=wp-block-heading&gt;2. Main Methods: The Lifecycle Controllers&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;Clears the reference from memory to prevent memory leaks, especially when switching between different models (e.g., switching from YOLO to Mask R-CNN).&lt;p class=wp-block-paragraph&gt;&lt;code&gt;loadModel()&lt;/code&gt;&lt;ol class=wp-block-list&gt;&lt;li&gt;Uses &lt;code&gt;getSafeModelAssetPath()&lt;/code&gt; to ensure model files exist in the sandbox.&lt;li&gt;Reads the files and initializes the OpenCV &lt;code&gt;Net&lt;/code&gt; object.&lt;li&gt;Stores the initialized &lt;code&gt;Net&lt;/code&gt; object in a cache (e.g., a &lt;code&gt;HashMap&lt;/code&gt; or a member variable) for immediate reuse.&lt;/ol&gt;&lt;p class=wp-block-paragraph&gt;&lt;code&gt;unloadModel()&lt;/code&gt;&lt;ol class=wp-block-list&gt;&lt;li&gt;Explicitly releases the resources held by the &lt;code&gt;Net&lt;/code&gt; object.&lt;li&gt;Clears the reference from memory to prevent memory leaks, especially when switching between different models (e.g., switching from YOLO to Mask R-CNN).&lt;/ol&gt;&lt;h4 class=wp-block-heading&gt;3. Efficient Model Management via Map&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;In the &lt;code&gt;loadModel()&lt;/code&gt; method, the &lt;code&gt;Net&lt;/code&gt; object is created using the model files prepared in the sandbox. To optimize performance, these objects are stored in a &lt;code&gt;Map&amp;lt;ModelType, Net&amp;gt;&lt;/code&gt;.&lt;p class=wp-block-paragraph&gt;The Logic of the Map Object:&lt;ul class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;Key&lt;/strong&gt;: The specific model type selected by the user (e.g., &lt;code&gt;YOLO_V3&lt;/code&gt;, &lt;code&gt;SSD&lt;/code&gt;).&lt;li&gt;&lt;strong&gt;Value&lt;/strong&gt;: The fully initialized OpenCV &lt;code&gt;Net&lt;/code&gt; object.&lt;/ul&gt;&lt;h4 class=wp-block-heading&gt;4. Conditional Assignment:&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;When &lt;code&gt;loadModel()&lt;/code&gt; is called, the repository follows this workflow:&lt;ol class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;Check Key&lt;/strong&gt;: It checks if the &lt;code&gt;Map&lt;/code&gt; already contains the &lt;code&gt;Net&lt;/code&gt; object for the requested model type.&lt;li&gt;&lt;strong&gt;Reuse&lt;/strong&gt;: If it exists, the repository simply returns the existing object, avoiding expensive disk I/O and memory allocation.&lt;li&gt;&lt;strong&gt;Create &amp;amp; Save&lt;/strong&gt;: Only if the object does &lt;strong&gt;not exist&lt;/strong&gt; (null), it creates a new &lt;code&gt;Net&lt;/code&gt; object using the model files and saves it to the &lt;code&gt;Map&lt;/code&gt; for future use.&lt;/ol&gt;&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: java; title: ; notranslate&#34;&gt;public Net loadModel(DetectorNetData.CvDetectorType modelType, String pbPath, String pbtxtPath) {&#xA;&#x9;String modelKey =modelType.toString();&#xA;&#xA;&#x9;if(modelType == DetectorNetData.CvDetectorType.METHOD_MRCNN || modelType == DetectorNetData.CvDetectorType.METHOD_MOBNET)&#xA;&#x9;{&#xA;&#x9;&#x9;if (!modelMap.containsKey(modelKey) || Objects.requireNonNull(modelMap.get(modelKey)).empty()) {&#xA;&#x9;&#x9;&#x9;Net net = Dnn.readNetFromTensorflow(pbPath, pbtxtPath);&#xA;&#x9;&#x9;&#x9;net.setPreferableBackend(Dnn.DNN_BACKEND_OPENCV);&#xA;&#x9;&#x9;&#x9;net.setPreferableTarget(Dnn.DNN_TARGET_CPU);&#xA;&#x9;&#x9;&#x9;modelMap.put(modelKey, net);&#xA;&#x9;&#x9;}&#xA;&#x9;&#x9;return modelMap.get(modelKey);&#xA;&#x9;}&#xA;&#x9;else if(modelType == DetectorNetData.CvDetectorType.METHOD_YOLOV3 ||&#xA;                modelType == DetectorNetData.CvDetectorType.METHOD_YOLOV3_TINY || &#xA;                modelType == DetectorNetData.CvDetectorType.METHOD_YOLOV7_TINY)&#xA;&#x9;{&#xA;&#x9;&#x9;if (!modelMap.containsKey(modelKey) || Objects.requireNonNull(modelMap.get(modelKey)).empty()) {&#xA;&#x9;&#x9;&#x9;Net net = Dnn.readNetFromDarknet(pbtxtPath, pbPath);&#xA;&#x9;&#x9;&#x9;net.setPreferableBackend(Dnn.DNN_BACKEND_OPENCV);&#xA;&#x9;&#x9;&#x9;net.setPreferableTarget(Dnn.DNN_TARGET_CPU);&#xA;&#x9;&#x9;&#x9;modelMap.put(modelKey, net);&#xA;&#x9;&#x9;}&#xA;&#x9;&#x9;return modelMap.get(modelKey);&#xA;&#x9;}&#xA;&#xA;&#x9;return null;&#xA;}&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;h4 class=wp-block-heading&gt;5. Explicit Memory Release via Map Removal&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;Just as we store models for reuse, we must also provide a way to remove the &lt;code&gt;Net&lt;/code&gt; objects from memory. By using the &lt;strong&gt;Model Type (Key)&lt;/strong&gt;, we can pinpoint and clear specific models from our internal &lt;code&gt;Map&lt;/code&gt;.&lt;p class=wp-block-paragraph&gt;The Unloading Process:&lt;ol start=1 class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;Identify Key&lt;/strong&gt;: The system identifies the model that is no longer needed (e.g., when a user deselects a model or closes the detection session).&lt;li&gt;&lt;strong&gt;Remove from Map&lt;/strong&gt;: The &lt;code&gt;Net&lt;/code&gt; object is removed from the &lt;code&gt;Map&lt;/code&gt; using its key.&lt;li&gt;&lt;strong&gt;Resource Cleanup&lt;/strong&gt;: Once removed from the &lt;code&gt;Map&lt;/code&gt;, the object becomes eligible for Garbage Collection. Since &lt;code&gt;Net&lt;/code&gt; objects are native resources in OpenCV, explicitly calling &lt;code&gt;net.release()&lt;/code&gt; (if available in the specific SDK version) before removal further ensures that native memory is freed immediately.&lt;/ol&gt;&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: java; title: ; notranslate&#34;&gt;public void unloadModel(String modelKey) {&#xA;&#x9;if (modelMap.containsKey(modelKey)) {&#xA;&#x9;&#x9;Net net = modelMap.get(modelKey);&#xA;&#x9;&#x9;if (net != null) {&#xA;&#x9;&#x9;&#x9;net = null; // de-referencing &#xA;&#x9;&#x9;}&#xA;&#x9;&#x9;modelMap.remove(modelKey);&#xA;&#x9;&#x9;System.gc(); // hints (needs sometimes because of heavy native memory)&#xA;&#x9;}&#xA;}&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;h4 class=wp-block-heading&gt;6. GUI Layouts&lt;/h4&gt;&lt;p class=wp-block-paragraph&gt;Our object detection app is designed with a clean, functional interface that prioritizes the camera feed while providing easy access to model selection.&lt;p class=wp-block-paragraph&gt;Key Components of the GUI:&lt;ol start=1 class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;Main Camera View&lt;/strong&gt;:&lt;ul class=wp-block-list&gt;&lt;li&gt;The center of the screen is dominated by the &lt;code&gt;CameraBridgeViewBase&lt;/code&gt;.&lt;li&gt;This is where the real-time frame processing happens. Once the user selects a model, the bounding boxes and labels are rendered directly on top of this view.&lt;/ul&gt;&lt;li&gt;&lt;strong&gt;Top Action Bar / Menu&lt;/strong&gt;:&lt;ul class=wp-block-list&gt;&lt;li&gt;Located at the top of the screen, it contains the &lt;strong&gt;Model Selection Menu&lt;/strong&gt;.&lt;li&gt;When the user clicks the menu icon, a list of available models (YOLO v3, YOLO v7, SSD, Mask R-CNN) appears.&lt;/ul&gt;&lt;li&gt;&lt;strong&gt;Status Overlays (Optional)&lt;/strong&gt;:&lt;ul class=wp-block-list&gt;&lt;li&gt;Information such as &lt;strong&gt;FPS (Frames Per Second)&lt;/strong&gt; or the name of the currently active model is often displayed in the corner to provide real-time feedback on performance.&lt;/ul&gt;&lt;/ol&gt;&lt;hr class=&#34;wp-block-separator has-alpha-channel-opacity&#34;&gt;&lt;h3 class=wp-block-heading&gt;&lt;a name=interaction_flow&gt;&lt;/a&gt;9.7. Interaction Flow&lt;/h3&gt;&lt;ul class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;Step 1&lt;/strong&gt;: The user launches the app, and the camera activates automatically via &lt;code&gt;enableView()&lt;/code&gt;.&lt;li&gt;&lt;strong&gt;Step 2&lt;/strong&gt;: The user taps the menu in the GUI.&lt;li&gt;&lt;strong&gt;Step 3&lt;/strong&gt;: Selecting a model triggers the &lt;code&gt;DnnModelRepository.loadModel()&lt;/code&gt; logic we discussed earlier.&lt;li&gt;&lt;strong&gt;Step 4&lt;/strong&gt;: The UI immediately reflects the detection results as the new &lt;code&gt;FrameRender&lt;/code&gt; starts drawing on the &lt;code&gt;onCameraFrame&lt;/code&gt;.&lt;/ul&gt;&lt;p class=wp-block-paragraph&gt;detection_xml.png 교체&lt;p class=wp-block-paragraph&gt;The menu on the left was created using &lt;code&gt;onCreateOptionsMenu()&lt;/code&gt;, and its selection logic is handled by the &lt;code&gt;onOptionsItemSelected()&lt;/code&gt; callback.&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: java; title: ; notranslate&#34;&gt;@Override&#xA;public boolean onCreateOptionsMenu(Menu menu) {&#xA;&#x9;super.onCreateOptionsMenu(menu);&#xA;&#x9;getMenuInflater().inflate(R.menu.detection, menu);&#xA;&#x9;return true;&#xA;}&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;p class=wp-block-paragraph&gt;The menu items consist of ‘Normal Mode’ as the default, with ‘YOLO’, ‘Mask R-CNN’, and ‘YOLO Tiny’ available as alternative detection models.&lt;h3 class=wp-block-heading&gt;&lt;a name=how_to_detect&gt;&lt;/a&gt;9.8. Object Detection Options&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;The application provides a variety of operational modes via the options menu. By default, the app starts in &lt;strong&gt;Normal Mode&lt;/strong&gt;, but users can switch to specialized inference models depending on their needs:&lt;ul class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;Normal Mode (Default)&lt;/strong&gt;: Standard camera preview without object detection processing.&lt;li&gt;&lt;strong&gt;YOLO&lt;/strong&gt;: The standard YOLO model, offering high accuracy for object detection.&lt;li&gt;&lt;strong&gt;Mask R-CNN&lt;/strong&gt;: Advanced model that provides instance segmentation (detecting object shapes).&lt;li&gt;&lt;strong&gt;YOLO Tiny&lt;/strong&gt;: A lightweight version of YOLO optimized for higher frame rates (FPS) on mobile devices.&lt;/ul&gt;&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: xml; title: ; notranslate&#34;&gt;&amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;utf-8&amp;#34;?&amp;gt;&#xA;&amp;lt;menu xmlns:android=&amp;#34;http://schemas.android.com/apk/res/android&amp;#34; &amp;gt;&#xA;    &amp;lt;group android:checkableBehavior=&amp;#34;single&amp;#34;&amp;gt;&#xA;        &amp;lt;item android:id=&amp;#34;@+id/normal_mode&amp;#34;&#xA;              android:title=&amp;#34;@string/normal_mode&amp;#34;&#xA;              android:showAsAction=&amp;#34;ifRoom|withText&amp;#34; /&amp;gt;&#xA;        &amp;lt;item&#xA;            android:id=&amp;#34;@+id/detect_mode&amp;#34;&#xA;            android:title=&amp;#34;@string/default_mode&amp;#34;&amp;gt;&#xA;              &amp;lt;menu&amp;gt;&#xA;                  &amp;lt;group android:checkableBehavior=&amp;#34;single&amp;#34;&amp;gt;&#xA;                      &amp;lt;item android:id=&amp;#34;@+id/normal&amp;#34;&#xA;                          android:title=&amp;#34;@string/normal&amp;#34;&#xA;                          android:checked=&amp;#34;true&amp;#34; /&amp;gt;&#xA;                      &amp;lt;item android:id=&amp;#34;@+id/maskrcnn&amp;#34;&#xA;                            android:title=&amp;#34;@string/maskrcnn&amp;#34; /&amp;gt;&#xA;                      &amp;lt;item android:id=&amp;#34;@+id/yolov3&amp;#34;&#xA;                            android:title=&amp;#34;@string/yolov3&amp;#34; /&amp;gt;&#xA;                      &amp;lt;item android:id=&amp;#34;@+id/yolov3_tiny&amp;#34;&#xA;                          android:title=&amp;#34;@string/yolov3_tiny&amp;#34; /&amp;gt;&#xA;                      &amp;lt;item android:id=&amp;#34;@+id/yolov7_tiny&amp;#34;&#xA;                          android:title=&amp;#34;@string/yolov7_tiny&amp;#34; /&amp;gt;&#xA;                      &amp;lt;item android:id=&amp;#34;@+id/mobile_net&amp;#34;&#xA;                          android:title=&amp;#34;@string/mobile_net&amp;#34; /&amp;gt;&#xA;                  &amp;lt;/group&amp;gt;&#xA;              &amp;lt;/menu&amp;gt;&#xA;        &amp;lt;/item&amp;gt;&#xA;    &amp;lt;/group&amp;gt;&#xA;&amp;lt;/menu&amp;gt;&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;p class=wp-block-paragraph&gt;The layout menu will be displayed on the real android device as follows:&lt;figure class=&#34;wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-6 is-layout-flex wp-block-gallery-is-layout-flex&#34;&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/05/Intro_icon.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/Intro_icon-1024x623.png decoding=async width=1024 height=623 data-id=143682 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/Intro_icon-1024x623.png alt class=wp-image-143682 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/Intro_icon-1024x623.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/Intro_icon-300x183.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/Intro_icon-768x468.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/Intro_icon-1536x935.png 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/Intro_icon.png 1549w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=623 data-id=143682 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/Intro_icon-1024x623.png alt class=wp-image-143682 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/Intro_icon-1024x623.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/Intro_icon-300x183.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/Intro_icon-768x468.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/Intro_icon-1536x935.png 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/Intro_icon.png 1549w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/05/user_options.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/user_options-1024x626.png decoding=async width=1024 height=626 data-id=143683 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/user_options-1024x626.png alt class=wp-image-143683 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/user_options-1024x626.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/user_options-300x183.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/user_options-768x469.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/user_options.png 1340w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=626 data-id=143683 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/user_options-1024x626.png alt class=wp-image-143683 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/user_options-1024x626.png 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/user_options-300x183.png 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/user_options-768x469.png 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/user_options.png 1340w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/figure&gt;&lt;p class=wp-block-paragraph&gt;The menu layout is rendered on the physical Android device as shown below, providing a seamless interface for switching between detection modes.&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: java; title: ; notranslate&#34;&gt;@Override&#xA;public boolean onOptionsItemSelected(MenuItem item) {&#xA;&#x9;boolean retBool = false;&#xA;&#xA;&#x9;int id = item.getItemId();&#xA;&#xA;&#x9;if(id == R.id.normal)&#xA;&#x9;{&#xA;&#x9;&#x9;Log.d(TAG, &amp;#34;Normal[&amp;#34;+item.getTitle()+&amp;#34;]&amp;#34;);&#xA;&#x9;&#x9;mOnCameraFrameRender =&#xA;&#x9;&#x9;&#x9;&#x9;new OnCameraFrameRender(new PreviewFrameRender());&#xA;&#x9;&#x9;item.setChecked(true);&#xA;&#x9;&#x9;retBool = true;&#xA;&#x9;}&#xA;&#x9;else if(id == R.id.maskrcnn)&#xA;&#x9;{&#xA;&#x9;&#x9;Log.d(TAG, &amp;#34;Mask RCNN[&amp;#34;+item.getTitle()+&amp;#34;]&amp;#34;);&#xA;&#x9;&#x9;mObjDetectorNet.preDetectorProcess(this, DetectorNetData.CvDetectorType.METHOD_MRCNN);&#xA;&#x9;&#x9;MaskRCNNFrameRender maskRCNNFrameRender = new MaskRCNNFrameRender(mObjDetectorNet);&#xA;&#x9;&#x9;mOnCameraFrameRender =&#xA;&#x9;&#x9;&#x9;&#x9;new OnCameraFrameRender(maskRCNNFrameRender);&#xA;&#xA;&#x9;&#x9;item.setChecked(true);&#xA;&#x9;&#x9;retBool = true;&#xA;&#x9;}&#xA;&#x9;else if(id == R.id.yolov3)&#xA;&#x9;{&#xA;&#x9;&#x9;Log.d(TAG, &amp;#34;Yolov3[&amp;#34;+item.getTitle()+&amp;#34;]&amp;#34;);&#xA;&#xA;&#x9;&#x9;mObjDetectorNet.preDetectorProcess(this, DetectorNetData.CvDetectorType.METHOD_YOLOV3);&#xA;&#x9;&#x9;YoloFrameRender yolov3FrameRender = new YoloFrameRender(mObjDetectorNet);&#xA;&#x9;&#x9;mOnCameraFrameRender =&#xA;&#x9;&#x9;&#x9;new OnCameraFrameRender(yolov3FrameRender);&#xA;&#xA;&#x9;&#x9;item.setChecked(true);&#xA;&#x9;&#x9;retBool = true;&#xA;&#x9;}&#xA;&#x9;else if(id == R.id.yolov3_tiny)&#xA;&#x9;{&#xA;&#x9;&#x9;Log.d(TAG, &amp;#34;Yolov3_tiny[&amp;#34;+item.getTitle()+&amp;#34;]&amp;#34;);&#xA;&#xA;&#x9;&#x9;mObjDetectorNet.preDetectorProcess(this, DetectorNetData.CvDetectorType.METHOD_YOLOV3_TINY);&#xA;&#x9;&#x9;YoloFrameRender yoloFrameRender = new YoloFrameRender(mObjDetectorNet);&#xA;&#x9;&#x9;mOnCameraFrameRender =&#xA;&#x9;&#x9;&#x9;&#x9;new OnCameraFrameRender(yoloFrameRender);&#xA;&#xA;&#x9;&#x9;item.setChecked(true);&#xA;&#x9;&#x9;retBool = true;&#xA;&#x9;}&#xA;&#x9;else if(id == R.id.yolov7_tiny)&#xA;&#x9;{&#xA;&#x9;&#x9;Log.d(TAG, &amp;#34;Yolov7_tiny[&amp;#34;+item.getTitle()+&amp;#34;]&amp;#34;);&#xA;&#xA;&#x9;&#x9;mObjDetectorNet.preDetectorProcess(this, DetectorNetData.CvDetectorType.METHOD_YOLOV7_TINY);&#xA;&#x9;&#x9;YoloFrameRender yoloFrameRender = new YoloFrameRender(mObjDetectorNet);&#xA;&#x9;&#x9;mOnCameraFrameRender =&#xA;&#x9;&#x9;&#x9;&#x9;new OnCameraFrameRender(yoloFrameRender);&#xA;&#xA;&#x9;&#x9;item.setChecked(true);&#xA;&#x9;&#x9;retBool = true;&#xA;&#x9;}&#xA;&#x9;else if(id == R.id.mobile_net)&#xA;&#x9;{&#xA;&#x9;&#x9;Log.d(TAG, &amp;#34;MobileNet[&amp;#34;+item.getTitle()+&amp;#34;]&amp;#34;);&#xA;&#xA;&#x9;&#x9;mObjDetectorNet.preDetectorProcess(this, DetectorNetData.CvDetectorType.METHOD_MOBNET);&#xA;&#x9;&#x9;MobileNetSSDFrameRender mobileNetSSDFrameRender = new MobileNetSSDFrameRender(mObjDetectorNet);&#xA;&#x9;&#x9;mOnCameraFrameRender =&#xA;&#x9;&#x9;&#x9;&#x9;new OnCameraFrameRender(mobileNetSSDFrameRender);&#xA;&#xA;&#x9;&#x9;item.setChecked(true);&#xA;&#x9;&#x9;retBool = true;&#xA;&#x9;}&#xA;&#x9;else&#xA;&#x9;{&#xA;&#x9;&#x9;mObjDetectorNet.preDetectorProcess(this, DetectorNetData.CvDetectorType.METHOD_NORMAL);&#xA;&#x9;&#x9;mOnCameraFrameRender = new OnCameraFrameRender(new PreviewFrameRender());&#xA;&#x9;&#x9;retBool = super.onOptionsItemSelected(item);&#xA;&#x9;}&#xA;&#x9;return retBool;&#xA;}&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;h3 class=wp-block-heading&gt;&lt;a name=object_detector_final&gt;&lt;/a&gt;9.9. Final Results of Object Detector&lt;/h3&gt;&lt;p class=wp-block-paragraph&gt;&lt;strong&gt;Finally, we have successfully built our object detector&lt;/strong&gt;, which runs inference properly whenever the user selects a detection option. With just a few minor modifications, &lt;strong&gt;you can easily test the latest object detection models on your own.&lt;/strong&gt;&lt;figure class=wp-block-table&gt;&lt;table class=has-fixed-layout&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Model Type&lt;td&gt;Output&lt;tr&gt;&lt;td&gt;Mask-RCNN&lt;td&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.MaskRCNN-1.jpg decoding=async width=2560 height=1551 class=wp-image-143688 style=&#34;width: 150px&#34; data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.MaskRCNN-1.jpg alt=1.MaskRCNN data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.MaskRCNN-1.jpg 2560w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.MaskRCNN-1-300x182.jpg 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.MaskRCNN-1-1024x620.jpg 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.MaskRCNN-1-768x465.jpg 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.MaskRCNN-1-1536x931.jpg 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.MaskRCNN-1-2048x1241.jpg 2048w&#34; data-sizes=&#34;(max-width: 2560px) 100vw, 2560px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=2560 height=1551 class=wp-image-143688 style=&#34;width: 150px&#34; src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.MaskRCNN-1.jpg alt=1.MaskRCNN srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.MaskRCNN-1.jpg 2560w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.MaskRCNN-1-300x182.jpg 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.MaskRCNN-1-1024x620.jpg 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.MaskRCNN-1-768x465.jpg 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.MaskRCNN-1-1536x931.jpg 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.MaskRCNN-1-2048x1241.jpg 2048w&#34; sizes=&#34;(max-width: 2560px) 100vw, 2560px&#34;&gt;&lt;/noscript&gt;&lt;tr&gt;&lt;td&gt;MobileNet-SSD v3&lt;td&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD.jpg decoding=async width=2560 height=1551 class=wp-image-143689 style=&#34;width: 150px&#34; data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD.jpg alt data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD.jpg 2560w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD-300x182.jpg 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD-1024x620.jpg 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD-768x465.jpg 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD-1536x931.jpg 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD-2048x1241.jpg 2048w&#34; data-sizes=&#34;(max-width: 2560px) 100vw, 2560px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=2560 height=1551 class=wp-image-143689 style=&#34;width: 150px&#34; src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD.jpg alt srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD.jpg 2560w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD-300x182.jpg 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD-1024x620.jpg 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD-768x465.jpg 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD-1536x931.jpg 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD-2048x1241.jpg 2048w&#34; sizes=&#34;(max-width: 2560px) 100vw, 2560px&#34;&gt;&lt;/noscript&gt;&lt;tr&gt;&lt;td&gt;Yolo v3&lt;td&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1.jpg decoding=async width=2560 height=1551 class=wp-image-143691 style=&#34;width: 150px&#34; data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1.jpg alt data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1.jpg 2560w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1-300x182.jpg 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1-1024x620.jpg 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1-768x465.jpg 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1-1536x931.jpg 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1-2048x1241.jpg 2048w&#34; data-sizes=&#34;(max-width: 2560px) 100vw, 2560px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=2560 height=1551 class=wp-image-143691 style=&#34;width: 150px&#34; src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1.jpg alt srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1.jpg 2560w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1-300x182.jpg 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1-1024x620.jpg 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1-768x465.jpg 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1-1536x931.jpg 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1-2048x1241.jpg 2048w&#34; sizes=&#34;(max-width: 2560px) 100vw, 2560px&#34;&gt;&lt;/noscript&gt;&lt;tr&gt;&lt;td&gt;Yolo v3 tiny&lt;td&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1.jpg decoding=async width=2560 height=1551 class=wp-image-143691 style=&#34;width: 150px&#34; data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1.jpg alt data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1.jpg 2560w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1-300x182.jpg 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1-1024x620.jpg 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1-768x465.jpg 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1-1536x931.jpg 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1-2048x1241.jpg 2048w&#34; data-sizes=&#34;(max-width: 2560px) 100vw, 2560px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=2560 height=1551 class=wp-image-143691 style=&#34;width: 150px&#34; src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1.jpg alt srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1.jpg 2560w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1-300x182.jpg 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1-1024x620.jpg 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1-768x465.jpg 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1-1536x931.jpg 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1-2048x1241.jpg 2048w&#34; sizes=&#34;(max-width: 2560px) 100vw, 2560px&#34;&gt;&lt;/noscript&gt;&lt;tr&gt;&lt;td&gt;Yolo v7 tiny&lt;td&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/5.YOLOv7-tiny-1.jpg decoding=async width=2560 height=1551 class=wp-image-143692 style=&#34;width: 150px&#34; data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/5.YOLOv7-tiny-1.jpg alt data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/5.YOLOv7-tiny-1.jpg 2560w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/5.YOLOv7-tiny-1-300x182.jpg 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/5.YOLOv7-tiny-1-1024x620.jpg 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/5.YOLOv7-tiny-1-768x465.jpg 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/5.YOLOv7-tiny-1-1536x931.jpg 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/5.YOLOv7-tiny-1-2048x1241.jpg 2048w&#34; data-sizes=&#34;(max-width: 2560px) 100vw, 2560px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=2560 height=1551 class=wp-image-143692 style=&#34;width: 150px&#34; src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/5.YOLOv7-tiny-1.jpg alt srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/5.YOLOv7-tiny-1.jpg 2560w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/5.YOLOv7-tiny-1-300x182.jpg 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/5.YOLOv7-tiny-1-1024x620.jpg 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/5.YOLOv7-tiny-1-768x465.jpg 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/5.YOLOv7-tiny-1-1536x931.jpg 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/5.YOLOv7-tiny-1-2048x1241.jpg 2048w&#34; sizes=&#34;(max-width: 2560px) 100vw, 2560px&#34;&gt;&lt;/noscript&gt;&lt;/table&gt;&lt;/figure&gt;&lt;figure class=&#34;wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-7 is-layout-flex wp-block-gallery-is-layout-flex&#34;&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/05/3.YOLOv3_.jpg&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/3.YOLOv3_-1024x620.jpg decoding=async width=1024 height=620 data-id=143685 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/3.YOLOv3_-1024x620.jpg alt=&#34;The output of maskrcnn model&#34; class=wp-image-143685 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/3.YOLOv3_-1024x620.jpg 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/3.YOLOv3_-300x182.jpg 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/3.YOLOv3_-768x465.jpg 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/3.YOLOv3_-1536x931.jpg 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/3.YOLOv3_-2048x1241.jpg 2048w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=620 data-id=143685 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/3.YOLOv3_-1024x620.jpg alt=&#34;The output of maskrcnn model&#34; class=wp-image-143685 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/3.YOLOv3_-1024x620.jpg 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/3.YOLOv3_-300x182.jpg 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/3.YOLOv3_-768x465.jpg 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/3.YOLOv3_-1536x931.jpg 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/3.YOLOv3_-2048x1241.jpg 2048w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny.jpg&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1024x620.jpg decoding=async width=1024 height=620 data-id=143686 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1024x620.jpg alt=&#34;The output of yolov3 tiny model&#34; class=wp-image-143686 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1024x620.jpg 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-300x182.jpg 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-768x465.jpg 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1536x931.jpg 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-2048x1241.jpg 2048w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=620 data-id=143686 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1024x620.jpg alt=&#34;The output of yolov3 tiny model&#34; class=wp-image-143686 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1024x620.jpg 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-300x182.jpg 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-768x465.jpg 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-1536x931.jpg 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/4.YOLOv3-tiny-2048x1241.jpg 2048w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/05/5.YOLOv7-tiny.jpg&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/5.YOLOv7-tiny-1024x620.jpg decoding=async width=1024 height=620 data-id=143687 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/5.YOLOv7-tiny-1024x620.jpg alt=&#34;The output of yolov7 tiny model&#34; class=wp-image-143687 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/5.YOLOv7-tiny-1024x620.jpg 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/5.YOLOv7-tiny-300x182.jpg 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/5.YOLOv7-tiny-768x465.jpg 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/5.YOLOv7-tiny-1536x931.jpg 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/5.YOLOv7-tiny-2048x1241.jpg 2048w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=620 data-id=143687 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/5.YOLOv7-tiny-1024x620.jpg alt=&#34;The output of yolov7 tiny model&#34; class=wp-image-143687 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/5.YOLOv7-tiny-1024x620.jpg 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/5.YOLOv7-tiny-300x182.jpg 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/5.YOLOv7-tiny-768x465.jpg 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/5.YOLOv7-tiny-1536x931.jpg 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/5.YOLOv7-tiny-2048x1241.jpg 2048w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;figure class=&#34;wp-block-image size-large&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD.jpg&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD-1024x620.jpg decoding=async width=1024 height=620 data-id=143689 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD-1024x620.jpg alt class=wp-image-143689 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD-1024x620.jpg 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD-300x182.jpg 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD-768x465.jpg 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD-1536x931.jpg 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD-2048x1241.jpg 2048w&#34; data-sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=1024 height=620 data-id=143689 src=https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD-1024x620.jpg alt class=wp-image-143689 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD-1024x620.jpg 1024w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD-300x182.jpg 300w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD-768x465.jpg 768w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD-1536x931.jpg 1536w, https://www.javacodegeeks.com/wp-content/uploads/2026/05/1.Mobile_SSD-2048x1241.jpg 2048w&#34; sizes=&#34;(max-width: 1024px) 100vw, 1024px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/figure&gt;&lt;p class=wp-block-paragraph&gt;Mobile-optimized models run significantly faster than older alternatives, which are often too slow for practical use. Furthermore, model accuracy varies widely. While I question the value of unoptimized models that lack sufficient performance, &lt;strong&gt;our current object detector layout allows us to test new models in the near future with minimal effort.&lt;/strong&gt;&lt;h2 class=wp-block-heading&gt;&lt;a name=summary&gt;&lt;/a&gt;10. Summary&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;In this series, we successfully developed a mobile application capable of real-time model switching and live object detection. You are now equipped to enhance this application by integrating custom-trained models or leveraging high-performance architectures to push the boundaries of your detection app.&lt;h2 class=wp-block-heading id=h-7-more-articles&gt;&lt;a name=references&gt;&lt;/a&gt;11. References&lt;/h2&gt;&lt;ul class=wp-block-list&gt;&lt;li&gt;&lt;a href=https://www.javacodegeeks.com/opencv-object-detection-java-swing-viewer.html target=_blank rel=&#34;noreferrer noopener&#34;&gt;OpenCV Object Detection Java Swing Viewer&lt;/a&gt;&lt;li&gt;&lt;a href=https://www.javacodegeeks.com/opencv-java-object-detection.html target=_blank rel=&#34;noreferrer noopener&#34;&gt;OpenCV Java Object Detection&lt;/a&gt;&lt;li&gt;&lt;a href=https://www.javacodegeeks.com/opencv-based-media-java-swing-viewer.html target=_blank rel=&#34;noreferrer noopener&#34;&gt;OpenCV-Based Media Java Swing Viewer&lt;/a&gt;&lt;/ul&gt;&lt;h2 class=wp-block-heading&gt;&lt;a name=links&gt;&lt;/a&gt;12. Download Links&lt;/h2&gt;&lt;ul class=wp-block-list&gt;&lt;li&gt;JDK (Java Development Kit) : &lt;a href=https://jdk.java.net/17/ target=_blank rel=&#34;noreferrer noopener&#34;&gt;https://jdk.java.net/17/&lt;/a&gt;&lt;li&gt;Android Studio : &lt;a href=&#34;https://developer.android.com/studio?hl=en&#34; target=_blank rel=&#34;noreferrer noopener&#34;&gt;https://developer.android.com/studio?hl=en&lt;/a&gt;&lt;li&gt;Gradle: &lt;a href=https://gradle.org/releases target=_blank rel=&#34;noreferrer noopener&#34;&gt;https://gradle.org/releases&lt;/a&gt;&lt;li&gt;OpenCV Android SDK : &lt;a href=https://github.com/opencv/opencv/releases/tag/4.13.0 target=_blank rel=&#34;noreferrer noopener&#34;&gt;https://github.com/opencv/opencv/releases/tag/4.13.0&lt;/a&gt;&lt;/ul&gt;&lt;h2 class=wp-block-heading&gt;&lt;a name=download_source&gt;&lt;/a&gt;13. Download the source code&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;The source code for this post is available for download. Keep in mind that &lt;strong&gt;the Object Detector App requires specific models and resources to run properly.&lt;/strong&gt; You can download these essential model files and assets in &lt;strong&gt;Section 14: Resources&lt;/strong&gt; below.&lt;div class=download&gt;&lt;strong&gt;Download&lt;/strong&gt;&lt;br&gt;&lt;br&gt;You can download the app source code of this post here:&lt;br&gt;&lt;br&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/05/my-hello-world.zip&gt;&lt;strong&gt;Hello World App&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/05/my-hello-opencv-1.zip&gt;&lt;strong&gt;Hello OpenCV App&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/05/my-object-detector.zip&gt;&lt;strong&gt;My Object Detector App&lt;/strong&gt;&lt;/a&gt;&lt;/div&gt;&lt;h2 class=wp-block-heading&gt;&lt;a name=download_howto&gt;&lt;/a&gt;14. How to Download Models and Resources&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;Due to upload size limits, the required models and labels are not included directly in this section. Instead, you can find the appropriate download links back in &lt;strong&gt;Section 9.3: Object Detection Process&lt;/strong&gt;. To run the Object Detector App successfully, simply download those necessary models and resources, then extract them directly into the &lt;code&gt;assets&lt;/code&gt; folder within your source directory.&lt;/p&gt;&lt;style&gt;.lepopup-progress-60 div.lepopup-progress-t1&gt;div{background-color:#e0e0e0;}.lepopup-progress-60 div.lepopup-progress-t1&gt;div&gt;div{background-color:#bd4070;}.lepopup-progress-60 div.lepopup-progress-t1&gt;div&gt;div{color:#ffffff;}.lepopup-progress-60 div.lepopup-progress-t1&gt;label{color:#444444;}.lepopup-form-60, .lepopup-form-60 *, .lepopup-progress-60 {font-size:15px;color:#444444;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-signature-box span i{font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#555555;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-signature-box,.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;text&#39;],.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;email&#39;],.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;password&#39;],.lepopup-form-60 .lepopup-element div.lepopup-input select,.lepopup-form-60 .lepopup-element div.lepopup-input select option,.lepopup-form-60 .lepopup-element div.lepopup-input textarea{font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#555555;font-style:normal;text-decoration:none;text-align:left;background-color:rgba(255, 255, 255, 0.7);background-image:none;border-width:1px;border-style:solid;border-color:#cccccc;border-radius:0px;box-shadow: inset 0px 0px 15px -7px #000000;}.lepopup-form-60 .lepopup-element div.lepopup-input ::placeholder{color:#555555; opacity: 0.9;} .lepopup-form-60 .lepopup-element div.lepopup-input ::-ms-input-placeholder{color:#555555; opacity: 0.9;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect::-webkit-scrollbar-thumb{background-color:#cccccc;}.lepopup-form-60 .lepopup-element div.lepopup-input&gt;i.lepopup-icon-left, .lepopup-form-60 .lepopup-element div.lepopup-input&gt;i.lepopup-icon-right{font-size:20px;color:#444444;border-radius:0px;}.lepopup-form-60 .lepopup-element .lepopup-button,.lepopup-form-60 .lepopup-element .lepopup-button:visited{font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#ffffff;font-weight:700;font-style:normal;text-decoration:none;text-align:center;background-color:#326693;background-image:none;border-width:1px;border-style:solid;border-color:#326693;border-radius:0px;box-shadow:none;}.lepopup-form-60 .lepopup-element div.lepopup-input .lepopup-imageselect+label{border-width:1px;border-style:solid;border-color:#cccccc;border-radius:0px;box-shadow:none;}.lepopup-form-60 .lepopup-element div.lepopup-input .lepopup-imageselect+label span.lepopup-imageselect-label{font-size:15px;color:#444444;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl:checked+label:after{background-color:rgba(255, 255, 255, 0.7);}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-classic+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-fa-check+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-square+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl+label{background-color:rgba(255, 255, 255, 0.7);border-color:#cccccc;color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-square:checked+label:after{background-color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl:checked+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl+label:after{background-color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-classic+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-fa-check+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-dot+label{background-color:rgba(255, 255, 255, 0.7);border-color:#cccccc;color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-dot:checked+label:after{background-color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect&gt;input[type=&#39;checkbox&#39;]+label:hover{background-color:#bd4070;color:#ffffff;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect&gt;input[type=&#39;checkbox&#39;]:checked+label{background-color:#a93a65;color:#ffffff;}.lepopup-form-60 .lepopup-element input[type=&#39;checkbox&#39;].lepopup-tile+label, .lepopup-form-60 .lepopup-element input[type=&#39;radio&#39;].lepopup-tile+label {font-size:15px;color:#444444;font-style:normal;text-decoration:none;text-align:center;background-color:#ffffff;background-image:none;border-width:1px;border-style:solid;border-color:#cccccc;border-radius:0px;box-shadow:none;}.lepopup-form-60 .lepopup-element-error{font-size:15px;color:#ffffff;font-style:normal;text-decoration:none;text-align:left;background-color:#d9534f;background-image:none;}.lepopup-form-60 .lepopup-element-2 {background-color:rgba(226, 236, 250, 1);background-image:none;border-width:1px;border-style:solid;border-color:rgba(216, 216, 216, 1);border-radius:3px;box-shadow: 1px 1px 15px -6px #d7e1eb;}.lepopup-form-60 .lepopup-element-3 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:26px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-3 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:26px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-3 .lepopup-element-html-content {min-height:73px;}.lepopup-form-60 .lepopup-element-4 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:19px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-4 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:19px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-4 .lepopup-element-html-content {min-height:23px;}.lepopup-form-60 .lepopup-element-5 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-5 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-5 .lepopup-element-html-content {min-height:24px;}.lepopup-form-60 .lepopup-element-6 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-6 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-6 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-7 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-7 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-7 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-8 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-8 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-8 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-9 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-9 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-9 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-10 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-10 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-10 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-11 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-11 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-11 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-12 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-12 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-12 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-13 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-13 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-13 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-14 div.lepopup-input .lepopup-icon-left, .lepopup-form-60 .lepopup-element-14 div.lepopup-input .lepopup-icon-right {line-height:36px;}.lepopup-form-60 .lepopup-element-15 div.lepopup-input{height:auto;line-height:1;}.lepopup-form-60 .lepopup-element-16 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:14px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-16 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:14px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-16 .lepopup-element-html-content {min-height:5px;}.lepopup-form-60 .lepopup-element-19 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#333333;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-19 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#333333;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-19 .lepopup-element-html-content {min-height:363px;}.lepopup-form-60 .lepopup-element-0 * {font-size:15px;color:#ffffff;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-0 {font-size:15px;color:#ffffff;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:#5cb85c;background-image:none;border-width:0px;border-style:solid;border-color:#ccc;border-radius:5px;box-shadow: 1px 1px 15px -6px #000000;padding-top:40px;padding-right:40px;padding-bottom:40px;padding-left:40px;}.lepopup-form-60 .lepopup-element-0 .lepopup-element-html-content {min-height:160px;}&lt;/style&gt;&lt;div class=lepopup-inline style=&#34;margin: 0 auto;&#34;&gt;&lt;div class=&#34;lepopup-form lepopup-form-60 lepopup-form-SwMvuNtoBC6QDxR6 lepopup-form-icon-inside lepopup-form-position-middle-right&#34; data-session=0 data-id=SwMvuNtoBC6QDxR6 data-form-id=60 data-slug=7lQM6oyWL5bTm5lw data-title=&#34;Under the Post Inline&#34; data-page=1 data-xd=off data-width=820 data-height=430 data-position=middle-right data-esc=off data-enter=on data-disable-scrollbar=off style=display:none;width:820px;height:430px; onclick=event.stopPropagation();&gt;&lt;div class=lepopup-form-inner style=width:820px;height:430px;&gt;&lt;div class=&#34;lepopup-element lepopup-element-2 lepopup-element-rectangle&#34; data-type=rectangle data-top=0 data-left=0 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:501;top:0px;left:0px;width:820px;height:430px;&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-3 lepopup-element-html&#34; data-type=html data-top=7 data-left=10 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:502;top:7px;left:10px;width:797px;height:73px;&gt;&lt;div class=lepopup-element-html-content&gt;Do you want to know how to develop your skillset to become a &lt;span style=&#34;color: #CAB43D; text-shadow: 1px 1px #835D5D;&#34;&gt;Java Rockstar?&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-4 lepopup-element-html&#34; data-type=html data-top=83 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:503;top:83px;left:308px;width:473px;height:23px;&gt;&lt;div class=lepopup-element-html-content&gt;Subscribe to our newsletter to start Rocking &lt;span style=&#34;text-decoration: underline;&#34;&gt;right now!&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-5 lepopup-element-html&#34; data-type=html data-top=107 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:504;top:107px;left:308px;width:473px;height:24px;&gt;&lt;div class=lepopup-element-html-content&gt;To get you started we give you our best selling eBooks for &lt;span style=&#34;color:#e01404; text-shadow: 1px 1px #C99924; font-size: 15px;&#34;&gt;FREE!&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-6 lepopup-element-html&#34; data-type=html data-top=136 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:505;top:136px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;1.&lt;/span&gt; JPA Mini Book&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-7 lepopup-element-html&#34; data-type=html data-top=156 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:506;top:156px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;2.&lt;/span&gt; JVM Troubleshooting Guide&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-8 lepopup-element-html&#34; data-type=html data-top=176 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:507;top:176px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;3.&lt;/span&gt; JUnit Tutorial for Unit Testing&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-9 lepopup-element-html&#34; data-type=html data-top=196 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:508;top:196px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;4.&lt;/span&gt; Java Annotations Tutorial&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-10 lepopup-element-html&#34; data-type=html data-top=216 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:509;top:216px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;5.&lt;/span&gt; Java Interview Questions&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-11 lepopup-element-html&#34; data-type=html data-top=236 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:510;top:236px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;6.&lt;/span&gt; Spring Interview Questions&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-12 lepopup-element-html&#34; data-type=html data-top=256 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:511;top:256px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;7.&lt;/span&gt; Android UI Design&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-13 lepopup-element-html&#34; data-type=html data-top=282 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:512;top:282px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;and many more ....&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-14&#34; data-type=email data-deps data-id=14 data-top=305 data-left=308 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:513;top:305px;left:308px;width:473px;height:36px;&gt;&lt;div class=lepopup-input&gt;&lt;input type=email name=lepopup-14 class=lepopup-ta-left placeholder=&#34;Enter your e-mail...&#34; autocomplete=email data-default aria-label=&#34;Email Field&#34; oninput=lepopup_input_changed(this); onfocus=lepopup_input_error_hide(this);&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-15&#34; data-type=checkbox data-deps data-id=15 data-top=344 data-left=308 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:514;top:344px;left:308px;width:160px;&gt;&lt;div class=&#34;lepopup-input lepopup-cr-layout-1 lepopup-cr-layout-left&#34;&gt;&lt;div class=&#34;lepopup-cr-container lepopup-cr-container-medium lepopup-cr-container-left&#34;&gt;&lt;div class=lepopup-cr-box&gt;&lt;input class=&#34;lepopup-checkbox lepopup-checkbox-classic lepopup-checkbox-medium&#34; type=checkbox name=lepopup-15[] id=lepopup-checkbox-9xLrCMWHEb4qZok2-14-0 value=on data-default=off onchange=lepopup_input_changed(this);&gt;&lt;label for=lepopup-checkbox-9xLrCMWHEb4qZok2-14-0 onclick=lepopup_input_error_hide(this);&gt;&lt;/label&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-cr-label lepopup-ta-left&#34;&gt;&lt;label for=lepopup-checkbox-9xLrCMWHEb4qZok2-14-0 onclick=lepopup_input_error_hide(this);&gt;&lt;/label&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-16 lepopup-element-html&#34; data-type=html data-top=344 data-left=338 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:515;top:344px;left:338px;width:350px;height:5px;&gt;&lt;div class=lepopup-element-html-content&gt;I agree to the &lt;a href=https://www.javacodegeeks.com/about/terms-of-use target=_blank&gt;Terms&lt;/a&gt; and &lt;a href=https://www.javacodegeeks.com/about/privacy-policy target=_blank&gt;Privacy Policy&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-17&#34; data-type=button data-top=372 data-left=308 data-animation-in=bounceIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:516;top:372px;left:308px;width:85px;height:37px;&gt;&lt;a class=&#34;lepopup-button lepopup-button-zoom-out&#34; href=https://www.javacodegeeks.com/feed/ onclick=&#34;return lepopup_submit(this);&#34; data-label=&#34;Sign up&#34; data-loading=Loading...&gt;&lt;span&gt;Sign up&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-19 lepopup-element-html&#34; data-type=html data-top=67 data-left=-15 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:518;top:67px;left:-15px;width:320px;height:363px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2015/01/books_promo.png decoding=async data-src=https://www.javacodegeeks.com/wp-content/uploads/2015/01/books_promo.png alt width=320 height=363&gt;&lt;noscript&gt;&lt;img decoding=async src=https://www.javacodegeeks.com/wp-content/uploads/2015/01/books_promo.png alt width=320 height=363&gt;&lt;/noscript&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-form lepopup-form-60 lepopup-form-SwMvuNtoBC6QDxR6 lepopup-form-icon-inside lepopup-form-position-middle-right&#34; data-session=0 data-id=SwMvuNtoBC6QDxR6 data-form-id=60 data-slug=7lQM6oyWL5bTm5lw data-title=&#34;Under the Post Inline&#34; data-page=confirmation data-xd=off data-width=420 data-height=320 data-position=middle-right data-esc=off data-enter=on data-disable-scrollbar=off style=display:none;width:420px;height:320px; onclick=event.stopPropagation();&gt;&lt;div class=lepopup-form-inner style=width:420px;height:320px;&gt;&lt;div class=&#34;lepopup-element lepopup-element-0 lepopup-element-html&#34; data-type=html data-top=80 data-left=70 data-animation-in=bounceInDown data-animation-out=fadeOutUp style=animation-duration:1000ms;animation-delay:0ms;z-index:500;top:80px;left:70px;width:280px;height:160px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;h4 style=&#34;text-align: center; font-size: 18px; font-weight: bold;&#34;&gt;Thank you!&lt;/h4&gt;&lt;p style=&#34;text-align: center;&#34;&gt;We will contact you soon.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;input type=hidden id=lepopup-logic-SwMvuNtoBC6QDxR6 value=[]&gt;&lt;/div&gt;&lt;div class=&#34;post-bottom-meta post-bottom-tags post-tags-classic&#34;&gt;&lt;div class=post-bottom-meta-title&gt;&lt;span class=tie-icon-tags aria-hidden=true&gt;&lt;/span&gt;Tags&lt;/div&gt;&lt;span class=tagcloud&gt;&lt;a href=https://www.javacodegeeks.com/tag/android rel=tag&gt;Android&lt;/a&gt; &lt;a href=https://www.javacodegeeks.com/tag/android-java rel=tag&gt;Android Java&lt;/a&gt; &lt;a href=https://www.javacodegeeks.com/tag/image-processing rel=tag&gt;Image Processing&lt;/a&gt; &lt;a href=https://www.javacodegeeks.com/tag/opencv rel=tag&gt;OpenCV&lt;/a&gt; &lt;a href=https://www.javacodegeeks.com/tag/opencvdnn-java-object-detection rel=tag&gt;OpenCVDNN Java Object Detection&lt;/a&gt; &lt;a href=https://www.javacodegeeks.com/tag/yolo rel=tag&gt;YOLO&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div id=post-extra-info&gt;&lt;div class=theiaStickySidebar&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=clearfix&gt;&lt;/div&gt;</description>
      <author>young.gon</author>
      <guid>https://www.javacodegeeks.com/opencv-android-object-detector.html</guid>
      <pubDate>Wed, 24 Jun 2026 09:44:28 +0000</pubDate>
    </item>
    <item>
      <title>Building and testing a Modern Java 25 / Spring Boot 4.0.6 Backend: Docker, PostgreSQL, OpenAPI, Serenity BDD, Cucumber, and JUnit 6</title>
      <link>https://www.javacodegeeks.com/building-and-testing-a-modern-java-25-spring-boot-4-0-6-backend-docker-postgresql-openapi-serenity-bdd-cucumber-and-junit-6.html</link>
      <description>&lt;header class=entry-header-outer&gt;&lt;nav id=breadcrumb&gt;&lt;a href=https://www.javacodegeeks.com/&gt;&lt;span class=tie-icon-home aria-hidden=true&gt;&lt;/span&gt;Home&lt;/a&gt;&lt;em class=delimiter&gt;»&lt;/em&gt;&lt;a href=https://www.javacodegeeks.com/category/java&gt;Java&lt;/a&gt;&lt;em class=delimiter&gt;»&lt;/em&gt;&lt;a href=https://www.javacodegeeks.com/category/java/enterprise-java&gt;Enterprise Java&lt;/a&gt;&lt;em class=delimiter&gt;»&lt;/em&gt;&lt;span class=current&gt;Building and testing a Modern Java 25 / Spring Boot 4.0.6 Backend: Docker, PostgreSQL, OpenAPI, Serenity BDD, Cucumber, and JUnit 6&lt;/span&gt;&lt;/nav&gt;&lt;div class=entry-header&gt;&lt;span class=post-cat-wrap&gt;&lt;a class=&#34;post-cat tie-cat-8&#34; href=https://www.javacodegeeks.com/category/java/enterprise-java&gt;Enterprise Java&lt;/a&gt;&lt;/span&gt;&lt;h1 class=&#34;post-title entry-title&#34;&gt;Building and testing a Modern Java 25 / Spring Boot 4.0.6 Backend: Docker, PostgreSQL, OpenAPI, Serenity BDD, Cucumber, and JUnit 6&lt;/h1&gt;&lt;/div&gt;&lt;/header&gt;&lt;div class=&#34;entry-content entry clearfix&#34;&gt;&lt;div class=&#34;stream-item stream-item-above-post-content&#34;&gt;&lt;div class=stream-item-size&gt;&lt;div id=adngin-in-post-0 style=&#34;float:left; margin-right:20px; margin-bottom:10px; width:300px; height:274px;&#34;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 class=wp-block-heading&gt;Abstract&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;This article walks through a compact but realistic backend application built with Java 25 and Spring Boot 4.0.6. The project uses PostgreSQL running in Docker, Gradle 9.5.1 as the build system, Eclipse 2026-03 as the IDE, springdoc OpenAPI/Swagger UI for interactive API documentation, and a test stack built around JUnit 6, Cucumber, and Serenity BDD. The purpose is not to teach every tool from first principles. Instead, the article provides a working integration baseline: a small book-catalog REST service that can be started, inspected through Swagger UI, tested through unit tests, and documented through Serenity reports. For developers who learn best by running real code and modifying it, this kind of baseline can be more useful than another isolated “hello world” example.&lt;h2 class=wp-block-heading&gt;Technology baseline&lt;/h2&gt;&lt;figure class=wp-block-table&gt;&lt;table class=has-fixed-layout&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Area&lt;/strong&gt;&lt;td&gt;&lt;strong&gt;Technology used in the project&lt;/strong&gt;&lt;tr&gt;&lt;td&gt;Language / runtime&lt;td&gt;Java 25&lt;tr&gt;&lt;td&gt;Application framework&lt;td&gt;Spring Boot 4.0.6&lt;tr&gt;&lt;td&gt;Build&lt;td&gt;Gradle 9.5.1, Groovy DSL, Java toolchains&lt;tr&gt;&lt;td&gt;Database&lt;td&gt;PostgreSQL 18.x running in Docker&lt;tr&gt;&lt;td&gt;API documentation&lt;td&gt;springdoc OpenAPI / Swagger UI&lt;tr&gt;&lt;td&gt;Testing&lt;td&gt;JUnit 6 / JUnit Jupiter, Cucumber, Serenity BDD, Serenity REST&lt;tr&gt;&lt;td&gt;IDE&lt;td&gt;Eclipse 2026-03&lt;tr&gt;&lt;td&gt;Application example&lt;td&gt;Book catalog REST API with create, read, update, delete, and search operations&lt;/table&gt;&lt;/figure&gt;&lt;h2 class=wp-block-heading&gt;Why another Spring Boot tutorial?&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;There is no shortage of Spring Boot examples. The problem is that many examples become outdated quickly. A tutorial written for Spring Boot 3.x, an older Gradle version, an older Docker Desktop release, or an older testing stack may still teach useful concepts, but it may also leave the reader solving version conflicts that the article never mentions.&lt;p class=wp-block-paragraph&gt;That version drift matters. Modern backend development is less about a single framework and more about the collaboration between framework, runtime, build system, database, test tools, API documentation, local development infrastructure, and IDE support. If one component moves forward while the others are frozen in older assumptions, developers often spend hours on dependency alignment, package moves, plugin versions, and configuration details.&lt;p class=wp-block-paragraph&gt;This article therefore takes a different angle. It demonstrates a small backend project where current versions work together. The goal is to provide a verified starting point rather than an encyclopedic treatment of every tool.&lt;h2 class=wp-block-heading&gt;The application used in the example&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;The sample application is intentionally simple: a book catalog service backed by PostgreSQL. It is simple enough to understand quickly, but it is not merely a console example. It has a database schema, a JPA entity, record-based request and response DTOs, a repository, a transactional service layer, a REST controller, centralized exception handling, OpenAPI documentation, unit tests, Cucumber scenarios, and Serenity-generated reports.&lt;p class=wp-block-paragraph&gt;The service exposes operations to list books, create a new book, retrieve a book by id, update an existing book, delete a book, search by author, and find a book by ISBN. This is enough surface area to demonstrate persistence, validation, error handling, documented REST endpoints, and several styles of automated testing.&lt;p class=wp-block-paragraph&gt;The table used by the application is intentionally small but includes realistic constraints:&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: sql; title: ; notranslate&#34;&gt;CREATE TABLE book (&#xA;    id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,&#xA;    title VARCHAR(200) NOT NULL,&#xA;    author VARCHAR(120) NOT NULL,&#xA;    isbn VARCHAR(20) NOT NULL,&#xA;    published_date DATE,&#xA;    price NUMERIC(10, 2),&#xA;    stock_quantity INTEGER NOT NULL,&#xA;    description VARCHAR(1000),&#xA;    CONSTRAINT uk_book_isbn UNIQUE (isbn),&#xA;    CONSTRAINT ck_book_price_nonnegative CHECK (price IS NULL OR price &amp;gt;= 0),&#xA;    CONSTRAINT ck_book_stock_nonnegative CHECK (stock_quantity &amp;gt;= 0)&#xA;);&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;h2 class=wp-block-heading&gt;Starting PostgreSQL with Docker&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;The database runs in a Docker container so that the example does not depend on a manually installed local PostgreSQL server. This keeps the development environment reproducible and makes it easier to reset or recreate the database when experimenting.&lt;p class=wp-block-paragraph&gt;A minimal development setup can start with pulling the PostgreSQL image and launching a named container. In real production environments, credentials should be injected through a secure mechanism rather than typed directly on the command line. For a local tutorial project, however, a direct command is sufficient to show the moving parts.&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: bash; title: ; notranslate&#34;&gt;docker pull postgres:latest&#xA;&#xA;docker run --name pg-akrivitsky   -e POSTGRES_USER=akrivitsky   -e POSTGRES_PASSWORD=your_password   -e POSTGRES_DB=swagger_demo   -p 5432:5432   -v pgdata_akrivitsky:/var/lib/postgresql   -d postgres:latest&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;p class=wp-block-paragraph&gt;The persistent volume is mapped to /var/lib/postgresql, which is the data directory location expected by the newer PostgreSQL Docker image used in this setup. After the container starts, the version can be verified with psql:&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: bash; title: ; notranslate&#34;&gt;docker exec -it pg-akrivitsky psql -U akrivitsky -d swagger_demo&#xA;SELECT version();&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;h2 class=wp-block-heading&gt;Gradle and Java 25&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;The project is a Gradle build using the Groovy DSL. The important point is that the build declares Java 25 through the Gradle toolchain mechanism. This is cleaner than relying on whatever JDK happens to be first on the PATH.&lt;p class=wp-block-paragraph&gt;The settings file can use the Foojay toolchain resolver convention plugin. Together with the toolchain declaration, this allows Gradle to resolve the requested JDK if it is not already installed in the local environment.&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: yaml; title: ; notranslate&#34;&gt;// settings.gradle&#xA;plugins {&#xA;    id &amp;#39;org.gradle.toolchains.foojay-resolver-convention&amp;#39; version &amp;#39;1.0.0&amp;#39;&#xA;}&#xA;&#xA;rootProject.name = &amp;#39;SpringBoot4FeaturesSwaggerSerenityPostgres&amp;#39;&#xA;include &amp;#39;lib&amp;#39;&#xA;&#xA;// lib/build.gradle&#xA;java {&#xA;    toolchain {&#xA;        languageVersion = JavaLanguageVersion.of(25)&#xA;    }&#xA;}&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;p class=wp-block-paragraph&gt;The build then applies the Spring Boot plugin, dependency management, Java, Eclipse, and Serenity plugin support. The exact dependency list is not complicated, but the versions are important because Spring Boot 4, springdoc 3.x, Serenity, Cucumber, and the JUnit platform must all cooperate.&lt;div style=&#34;display:inline-block; margin: 15px 0;&#34;&gt;&lt;div id=adngin-JavaCodeGeeks_incontent_video-0 style=display:inline-block;&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: yaml; title: ; notranslate&#34;&gt;plugins {&#xA;    id &amp;#39;java&amp;#39;&#xA;    id &amp;#39;eclipse&amp;#39;&#xA;    id &amp;#39;org.springframework.boot&amp;#39; version &amp;#39;4.0.6&amp;#39;&#xA;    id &amp;#39;io.spring.dependency-management&amp;#39; version &amp;#39;1.1.7&amp;#39;&#xA;    id &amp;#39;net.serenity-bdd.serenity-gradle-plugin&amp;#39; version &amp;#39;5.3.9&amp;#39;&#xA;}&#xA;&#xA;ext {&#xA;    serenityVersion = &amp;#39;5.3.9&amp;#39;&#xA;    cucumberVersion = &amp;#39;7.21.1&amp;#39;&#xA;}&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;h2 class=wp-block-heading&gt;Spring Boot 4.0.6 project structure&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;The application follows a conventional layered structure. The root package contains the Spring Boot application class. Subpackages hold configuration, controller, DTO, entity, exception, repository, and service code. Tests are separated into ordinary unit and slice tests, Cucumber step definitions, a Cucumber runner, and direct Serenity REST tests.&lt;p class=wp-block-paragraph&gt;This structure is not the only possible layout, but it is easy to understand and works well for a tutorial project. It also maps naturally to common enterprise development expectations: controller logic is separate from service logic, persistence is hidden behind Spring Data JPA repositories, and exception handling is centralized.&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: plain; title: ; notranslate&#34;&gt;src/main/java/dev/anatoly/swaggerdemo&#xA;├── SwaggerDemoApplication.java&#xA;├── config/OpenApiConfig.java&#xA;├── controller/BookController.java&#xA;├── dto/BookCreateRequest.java&#xA;├── dto/BookUpdateRequest.java&#xA;├── dto/BookResponse.java&#xA;├── entity/Book.java&#xA;├── exception/GlobalExceptionHandler.java&#xA;├── exception/ResourceNotFoundException.java&#xA;├── repository/BookRepository.java&#xA;└── service/BookService.java&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;h2 class=wp-block-heading&gt;Modern Java style in the DTO layer&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;The request and response objects are implemented as Java records. Records are not new to Java 25, but they represent a concise and reliable style for immutable data carriers. In a REST application they are especially convenient because they avoid boilerplate getters, setters, equals, hashCode, and toString code.&lt;p class=wp-block-paragraph&gt;Validation annotations can be applied directly to record components. springdoc can also read OpenAPI metadata from annotations placed on those components.&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: java; title: ; notranslate&#34;&gt;public record BookCreateRequest(&#xA;    @NotBlank&#xA;    @Schema(example = &amp;#34;Effective Java&amp;#34;)&#xA;    String title,&#xA;&#xA;    @NotBlank&#xA;    @Schema(example = &amp;#34;Joshua Bloch&amp;#34;)&#xA;    String author,&#xA;&#xA;    @NotBlank&#xA;    @ISBN&#xA;    @Schema(example = &amp;#34;9780134685991&amp;#34;)&#xA;    String isbn,&#xA;&#xA;    @PastOrPresent&#xA;    LocalDate publishedDate,&#xA;&#xA;    @DecimalMin(&amp;#34;0.00&amp;#34;)&#xA;    BigDecimal price,&#xA;&#xA;    @Min(0)&#xA;    Integer stockQuantity,&#xA;&#xA;    String description&#xA;) {}&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;h2 class=wp-block-heading&gt;Repository and service layer&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;The repository extends JpaRepository and uses Spring Data derived queries for the two non-basic lookup methods. This keeps the persistence layer compact and lets Spring Data create the implementation automatically.&lt;p class=wp-block-paragraph&gt;The service layer is transactional. Read operations can use read-only transactions, while create, update, and delete operations run in ordinary transactional context. Mapping between entity and record DTO is done manually to keep the example transparent and avoid reflection-heavy mapping frameworks.&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: java; title: ; notranslate&#34;&gt;public interface BookRepository extends JpaRepository&amp;lt;Book, Long&amp;gt; {&#xA;    Optional&amp;lt;Book&amp;gt; findByIsbn(String isbn);&#xA;    List&amp;lt;Book&amp;gt; findByAuthorContainingIgnoreCase(String author);&#xA;}&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;h2 class=wp-block-heading&gt;REST API and OpenAPI documentation&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;The REST controller exposes the book-catalog operations and annotates them with OpenAPI metadata. Swagger UI then becomes more than a static documentation page. It is also a convenient manual exploration tool: developers can inspect endpoints, send requests, view responses, and confirm that the application is connected to PostgreSQL.&lt;p class=wp-block-paragraph&gt;In a production system, Swagger UI access should be controlled according to organizational security rules. For a local development baseline, it is very useful because it provides immediate feedback before the test suite is executed.&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: java; title: ; notranslate&#34;&gt;@RestController&#xA;@RequestMapping(&amp;#34;/api/books&amp;#34;)&#xA;@Tag(name = &amp;#34;Books&amp;#34;, description = &amp;#34;CRUD operations for catalog entries&amp;#34;)&#xA;public class BookController {&#xA;&#xA;    private final BookService bookService;&#xA;&#xA;    public BookController(BookService bookService) {&#xA;        this.bookService = bookService;&#xA;    }&#xA;&#xA;    @GetMapping&#xA;    @Operation(summary = &amp;#34;List all books&amp;#34;)&#xA;    public List&amp;lt;BookResponse&amp;gt; listBooks() {&#xA;        return bookService.findAll();&#xA;    }&#xA;&#xA;    @PostMapping&#xA;    @Operation(summary = &amp;#34;Create a new book&amp;#34;)&#xA;    public ResponseEntity&amp;lt;BookResponse&amp;gt; createBook(@Valid @RequestBody BookCreateRequest request) {&#xA;        BookResponse created = bookService.create(request);&#xA;        return ResponseEntity.status(HttpStatus.CREATED).body(created);&#xA;    }&#xA;}&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;h2 class=wp-block-heading&gt;Application configuration&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;The application.yaml file connects the Spring Boot application to the PostgreSQL container, enables SQL initialization, configures JPA validation against the schema, and exposes the OpenAPI/Swagger endpoints. One notable property is virtual thread support, enabled with a single Spring Boot configuration line.&lt;p class=wp-block-paragraph&gt;Virtual threads are not required for this small example, but enabling them demonstrates how the project can use a modern Java runtime feature through Spring Boot configuration.&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: yaml; title: ; notranslate&#34;&gt;server:&#xA;  port: 8080&#xA;&#xA;spring:&#xA;  threads:&#xA;    virtual:&#xA;      enabled: true&#xA;  datasource:&#xA;    url: jdbc:postgresql://localhost:5432/swagger_demo&#xA;    username: akrivitsky&#xA;    password: your_password&#xA;  jpa:&#xA;    hibernate:&#xA;      ddl-auto: validate&#xA;  sql:&#xA;    init:&#xA;      mode: always&#xA;&#xA;springdoc:&#xA;  swagger-ui:&#xA;    path: /swagger-ui.html&#xA;  api-docs:&#xA;    path: /v3/api-docs&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;h2 class=wp-block-heading&gt;Error handling with ProblemDetail&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;Modern Spring applications do not need to invent a custom error object for every REST API. Spring supports ProblemDetail, which is aligned with the standardized problem-details response style. In the sample project, a global exception handler converts application exceptions and validation failures into structured error responses.&lt;p class=wp-block-paragraph&gt;This approach keeps controller methods cleaner and gives API clients a predictable error-response shape.&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: java; title: ; notranslate&#34;&gt;@RestControllerAdvice&#xA;public class GlobalExceptionHandler {&#xA;&#xA;    @ExceptionHandler(ResourceNotFoundException.class)&#xA;    public ProblemDetail handleNotFound(ResourceNotFoundException ex) {&#xA;        ProblemDetail problem = ProblemDetail.forStatus(HttpStatus.NOT_FOUND);&#xA;        problem.setTitle(&amp;#34;Resource not found&amp;#34;);&#xA;        problem.setDetail(ex.getMessage());&#xA;        return problem;&#xA;    }&#xA;}&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;h2 class=wp-block-heading&gt;Testing strategy&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;The project deliberately uses more than one testing style because real projects rarely rely on one style only. The ordinary Gradle test task runs unit and Spring tests. Cucumber feature tests are placed behind a separate task so that they do not accidentally run during every ordinary test execution. Serenity is then used to generate human-readable reports.&lt;p class=wp-block-paragraph&gt;This separation gives developers control. Fast unit tests can run frequently. Cucumber and Serenity acceptance tests can run when the application is available and when report generation is useful.&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: java; title: ; notranslate&#34;&gt;test {&#xA;    useJUnitPlatform {&#xA;        excludeEngines &amp;#39;cucumber&amp;#39;&#xA;    }&#xA;}&#xA;&#xA;task cucumberTest(type: Test) {&#xA;    useJUnitPlatform {&#xA;        includeEngines &amp;#39;junit-platform-suite&amp;#39;, &amp;#39;cucumber&amp;#39;&#xA;    }&#xA;    systemProperty &amp;#39;cucumber.features&amp;#39;, &amp;#39;classpath:features/books&amp;#39;&#xA;    systemProperty &amp;#39;cucumber.glue&amp;#39;, &amp;#39;dev.anatoly.swaggerdemo.cucumber&amp;#39;&#xA;    filter {&#xA;        includeTestsMatching &amp;#34;*RunCucumberTest*&amp;#34;&#xA;    }&#xA;}&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;h2 class=wp-block-heading&gt;Cucumber plus Serenity BDD&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;Cucumber is useful when tests should read like business behavior. In this project, a feature file describes book search behavior in Given/When/Then form. Java step definitions execute those steps by calling the running REST API through Serenity REST.&lt;p class=wp-block-paragraph&gt;The result is not only pass/fail automation. Serenity produces a report that documents the executed scenario, request, response, headers, body, and outcome. This can be valuable when test results must be understandable to people who are not reading Java source code.&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: plain; title: ; notranslate&#34;&gt;Feature: Search books&#xA;&#xA;  Scenario: Find books by author&#xA;    Given the book catalog service is running&#xA;    When I search books by author &amp;#34;Martin&amp;#34;&#xA;    Then the response status should be 200&#xA;    And the response should contain at least one book&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;h2 class=wp-block-heading&gt;Serenity REST without Gherkin&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;The project also demonstrates another style: direct JUnit 6 / JUnit Jupiter tests using Serenity REST, without .feature files. This is useful when the audience for the tests is mainly technical and when the extra Gherkin layer does not add much value.&lt;p class=wp-block-paragraph&gt;In this style the test remains an ordinary Java test, but Serenity still captures the REST interaction and generates a rich HTML report.&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: java; title: ; notranslate&#34;&gt;@ExtendWith(SerenityJUnit5Extension.class)&#xA;class WhenManagingBooks {&#xA;&#xA;    @Test&#xA;    void should_find_books_by_author() {&#xA;        SerenityRest.given()&#xA;            .queryParam(&amp;#34;author&amp;#34;, &amp;#34;Martin&amp;#34;)&#xA;        .when()&#xA;            .get(&amp;#34;http://localhost:8080/api/books/search/by-author&amp;#34;)&#xA;        .then()&#xA;            .statusCode(200);&#xA;    }&#xA;}&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;h2 class=wp-block-heading&gt;Running the application&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;Once PostgreSQL is running, the application can be started from Eclipse by running the Spring Boot application class as a Java application. After startup, Swagger UI can be opened in the browser.&lt;p class=wp-block-paragraph&gt;The Swagger UI page provides a convenient way to verify the endpoints manually. For example, you can create a new book by sending a JSON request to the POST /api/books endpoint and then confirm that the saved record appears in later GET responses.&lt;div class=wp-block-syntaxhighlighter-code&gt;&lt;pre class=&#34;brush: plain; title: ; notranslate&#34;&gt;http://localhost:8080/swagger-ui/index.html&#xA;&#xA;# Cucumber + Serenity reports&#xA;gradlew :lib:clean :lib:cucumberTest :lib:aggregate --rerun-tasks&#xA;&#xA;# Direct JUnit / Serenity REST report&#xA;gradlew :lib:clean :lib:test --tests &amp;#34;*WhenManagingBooks*&amp;#34; :lib:aggregate --rerun-tasks&#xA;&lt;/pre&gt;&lt;/div&gt;&lt;h2 class=wp-block-heading&gt;What this project gives you&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;The practical value of the project is the integration baseline. It shows one combination of Spring Boot 4.0.6, Java 25, PostgreSQL in Docker, Gradle, OpenAPI documentation, and Serenity-based testing that works as a coherent unit.&lt;p class=wp-block-paragraph&gt;That does not mean every production system should copy this project exactly. Production deployments require stricter secrets management, environment-specific configuration, observability, CI/CD hardening, infrastructure automation, and security review. The point is to start from a running, tested, documented example rather than from incompatible fragments.&lt;p class=wp-block-paragraph&gt;Docker Compose or Kubernetes can be added later if the article is extended. For the present baseline, a single PostgreSQL container is enough to demonstrate local database infrastructure without making the article primarily about orchestration.&lt;h2 class=wp-block-heading&gt;Lessons learned&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;First, version alignment is the hidden work in modern tutorials. Spring Boot, springdoc, Gradle, Java, Cucumber, Serenity, PostgreSQL, and the JUnit platform all evolve. A useful example must show versions that actually cooperate.&lt;p class=wp-block-paragraph&gt;Second, API documentation and testing should not be afterthoughts. Swagger UI gives a fast manual feedback loop. Unit tests give development confidence. Cucumber and Serenity reports add readable evidence of API behavior.&lt;p class=wp-block-paragraph&gt;Third, AI-assisted development can speed up the search for working configurations, but it does not remove the need to verify. In this project, every useful generated fragment still had to be compiled, run, tested, and corrected locally. That is the responsible version of a vibe-coding workflow: use AI as an accelerator, not as an authority.&lt;h2 class=wp-block-heading&gt;Conclusion&lt;/h2&gt;&lt;p class=wp-block-paragraph&gt;A modern Java backend is rarely just Java code. It is a working relationship between the language, the framework, the build, the database, the local infrastructure, the documentation surface, and the test/reporting workflow.&lt;p class=wp-block-paragraph&gt;This article presented a compact Spring Boot 4.0.6 / Java 25 project that connects those pieces in one place. The application is small, but the stack is representative of real enterprise development: PostgreSQL persistence, Docker-based local infrastructure, OpenAPI documentation, JUnit 6 tests, Cucumber scenarios, and Serenity BDD reporting.&lt;p class=wp-block-paragraph&gt;For developers who prefer learning through a running project, this baseline can be cloned, inspected, tested, and modified. From there, it can grow into Docker Compose, Kubernetes, CI/CD pipelines, additional security controls, or a larger domain model.&lt;p class=wp-block-paragraph&gt;&lt;strong&gt;Source code: &lt;/strong&gt;&lt;a href=https://github.com/akrivitsky7/springboot4-swagger-serenity-postgres-eclipse/tree/main target=_blank rel=&#34;noreferrer noopener&#34;&gt;&lt;strong&gt;https://github.com/akrivitsky7/springboot4-swagger-serenity-postgres-eclipse/tree/main&lt;/strong&gt;&lt;/a&gt;&lt;p class=wp-block-paragraph&gt;&lt;style&gt;.lepopup-progress-60 div.lepopup-progress-t1&gt;div{background-color:#e0e0e0;}.lepopup-progress-60 div.lepopup-progress-t1&gt;div&gt;div{background-color:#bd4070;}.lepopup-progress-60 div.lepopup-progress-t1&gt;div&gt;div{color:#ffffff;}.lepopup-progress-60 div.lepopup-progress-t1&gt;label{color:#444444;}.lepopup-form-60, .lepopup-form-60 *, .lepopup-progress-60 {font-size:15px;color:#444444;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-signature-box span i{font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#555555;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-signature-box,.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;text&#39;],.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;email&#39;],.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;password&#39;],.lepopup-form-60 .lepopup-element div.lepopup-input select,.lepopup-form-60 .lepopup-element div.lepopup-input select option,.lepopup-form-60 .lepopup-element div.lepopup-input textarea{font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#555555;font-style:normal;text-decoration:none;text-align:left;background-color:rgba(255, 255, 255, 0.7);background-image:none;border-width:1px;border-style:solid;border-color:#cccccc;border-radius:0px;box-shadow: inset 0px 0px 15px -7px #000000;}.lepopup-form-60 .lepopup-element div.lepopup-input ::placeholder{color:#555555; opacity: 0.9;} .lepopup-form-60 .lepopup-element div.lepopup-input ::-ms-input-placeholder{color:#555555; opacity: 0.9;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect::-webkit-scrollbar-thumb{background-color:#cccccc;}.lepopup-form-60 .lepopup-element div.lepopup-input&gt;i.lepopup-icon-left, .lepopup-form-60 .lepopup-element div.lepopup-input&gt;i.lepopup-icon-right{font-size:20px;color:#444444;border-radius:0px;}.lepopup-form-60 .lepopup-element .lepopup-button,.lepopup-form-60 .lepopup-element .lepopup-button:visited{font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#ffffff;font-weight:700;font-style:normal;text-decoration:none;text-align:center;background-color:#326693;background-image:none;border-width:1px;border-style:solid;border-color:#326693;border-radius:0px;box-shadow:none;}.lepopup-form-60 .lepopup-element div.lepopup-input .lepopup-imageselect+label{border-width:1px;border-style:solid;border-color:#cccccc;border-radius:0px;box-shadow:none;}.lepopup-form-60 .lepopup-element div.lepopup-input .lepopup-imageselect+label span.lepopup-imageselect-label{font-size:15px;color:#444444;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl:checked+label:after{background-color:rgba(255, 255, 255, 0.7);}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-classic+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-fa-check+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-square+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl+label{background-color:rgba(255, 255, 255, 0.7);border-color:#cccccc;color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-square:checked+label:after{background-color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl:checked+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl+label:after{background-color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-classic+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-fa-check+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-dot+label{background-color:rgba(255, 255, 255, 0.7);border-color:#cccccc;color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-dot:checked+label:after{background-color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect&gt;input[type=&#39;checkbox&#39;]+label:hover{background-color:#bd4070;color:#ffffff;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect&gt;input[type=&#39;checkbox&#39;]:checked+label{background-color:#a93a65;color:#ffffff;}.lepopup-form-60 .lepopup-element input[type=&#39;checkbox&#39;].lepopup-tile+label, .lepopup-form-60 .lepopup-element input[type=&#39;radio&#39;].lepopup-tile+label {font-size:15px;color:#444444;font-style:normal;text-decoration:none;text-align:center;background-color:#ffffff;background-image:none;border-width:1px;border-style:solid;border-color:#cccccc;border-radius:0px;box-shadow:none;}.lepopup-form-60 .lepopup-element-error{font-size:15px;color:#ffffff;font-style:normal;text-decoration:none;text-align:left;background-color:#d9534f;background-image:none;}.lepopup-form-60 .lepopup-element-2 {background-color:rgba(226, 236, 250, 1);background-image:none;border-width:1px;border-style:solid;border-color:rgba(216, 216, 216, 1);border-radius:3px;box-shadow: 1px 1px 15px -6px #d7e1eb;}.lepopup-form-60 .lepopup-element-3 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:26px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-3 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:26px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-3 .lepopup-element-html-content {min-height:73px;}.lepopup-form-60 .lepopup-element-4 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:19px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-4 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:19px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-4 .lepopup-element-html-content {min-height:23px;}.lepopup-form-60 .lepopup-element-5 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-5 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-5 .lepopup-element-html-content {min-height:24px;}.lepopup-form-60 .lepopup-element-6 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-6 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-6 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-7 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-7 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-7 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-8 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-8 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-8 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-9 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-9 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-9 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-10 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-10 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-10 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-11 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-11 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-11 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-12 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-12 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-12 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-13 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-13 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-13 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-14 div.lepopup-input .lepopup-icon-left, .lepopup-form-60 .lepopup-element-14 div.lepopup-input .lepopup-icon-right {line-height:36px;}.lepopup-form-60 .lepopup-element-15 div.lepopup-input{height:auto;line-height:1;}.lepopup-form-60 .lepopup-element-16 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:14px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-16 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:14px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-16 .lepopup-element-html-content {min-height:5px;}.lepopup-form-60 .lepopup-element-19 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#333333;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-19 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#333333;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-19 .lepopup-element-html-content {min-height:363px;}.lepopup-form-60 .lepopup-element-0 * {font-size:15px;color:#ffffff;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-0 {font-size:15px;color:#ffffff;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:#5cb85c;background-image:none;border-width:0px;border-style:solid;border-color:#ccc;border-radius:5px;box-shadow: 1px 1px 15px -6px #000000;padding-top:40px;padding-right:40px;padding-bottom:40px;padding-left:40px;}.lepopup-form-60 .lepopup-element-0 .lepopup-element-html-content {min-height:160px;}&lt;/style&gt;&lt;div class=lepopup-inline style=&#34;margin: 0 auto;&#34;&gt;&lt;div class=&#34;lepopup-form lepopup-form-60 lepopup-form-G1tq3YAxHwpQPxQk lepopup-form-icon-inside lepopup-form-position-middle-right&#34; data-session=0 data-id=G1tq3YAxHwpQPxQk data-form-id=60 data-slug=7lQM6oyWL5bTm5lw data-title=&#34;Under the Post Inline&#34; data-page=1 data-xd=off data-width=820 data-height=430 data-position=middle-right data-esc=off data-enter=on data-disable-scrollbar=off style=display:none;width:820px;height:430px; onclick=event.stopPropagation();&gt;&lt;div class=lepopup-form-inner style=width:820px;height:430px;&gt;&lt;div class=&#34;lepopup-element lepopup-element-2 lepopup-element-rectangle&#34; data-type=rectangle data-top=0 data-left=0 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:501;top:0px;left:0px;width:820px;height:430px;&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-3 lepopup-element-html&#34; data-type=html data-top=7 data-left=10 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:502;top:7px;left:10px;width:797px;height:73px;&gt;&lt;div class=lepopup-element-html-content&gt;Do you want to know how to develop your skillset to become a &lt;span style=&#34;color: #CAB43D; text-shadow: 1px 1px #835D5D;&#34;&gt;Java Rockstar?&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-4 lepopup-element-html&#34; data-type=html data-top=83 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:503;top:83px;left:308px;width:473px;height:23px;&gt;&lt;div class=lepopup-element-html-content&gt;Subscribe to our newsletter to start Rocking &lt;span style=&#34;text-decoration: underline;&#34;&gt;right now!&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-5 lepopup-element-html&#34; data-type=html data-top=107 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:504;top:107px;left:308px;width:473px;height:24px;&gt;&lt;div class=lepopup-element-html-content&gt;To get you started we give you our best selling eBooks for &lt;span style=&#34;color:#e01404; text-shadow: 1px 1px #C99924; font-size: 15px;&#34;&gt;FREE!&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-6 lepopup-element-html&#34; data-type=html data-top=136 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:505;top:136px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;1.&lt;/span&gt; JPA Mini Book&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-7 lepopup-element-html&#34; data-type=html data-top=156 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:506;top:156px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;2.&lt;/span&gt; JVM Troubleshooting Guide&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-8 lepopup-element-html&#34; data-type=html data-top=176 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:507;top:176px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;3.&lt;/span&gt; JUnit Tutorial for Unit Testing&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-9 lepopup-element-html&#34; data-type=html data-top=196 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:508;top:196px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;4.&lt;/span&gt; Java Annotations Tutorial&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-10 lepopup-element-html&#34; data-type=html data-top=216 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:509;top:216px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;5.&lt;/span&gt; Java Interview Questions&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-11 lepopup-element-html&#34; data-type=html data-top=236 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:510;top:236px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;6.&lt;/span&gt; Spring Interview Questions&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-12 lepopup-element-html&#34; data-type=html data-top=256 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:511;top:256px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;7.&lt;/span&gt; Android UI Design&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-13 lepopup-element-html&#34; data-type=html data-top=282 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:512;top:282px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;and many more ....&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-14&#34; data-type=email data-deps data-id=14 data-top=305 data-left=308 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:513;top:305px;left:308px;width:473px;height:36px;&gt;&lt;div class=lepopup-input&gt;&lt;input type=email name=lepopup-14 class=lepopup-ta-left placeholder=&#34;Enter your e-mail...&#34; autocomplete=email data-default aria-label=&#34;Email Field&#34; oninput=lepopup_input_changed(this); onfocus=lepopup_input_error_hide(this);&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-15&#34; data-type=checkbox data-deps data-id=15 data-top=344 data-left=308 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:514;top:344px;left:308px;width:160px;&gt;&lt;div class=&#34;lepopup-input lepopup-cr-layout-1 lepopup-cr-layout-left&#34;&gt;&lt;div class=&#34;lepopup-cr-container lepopup-cr-container-medium lepopup-cr-container-left&#34;&gt;&lt;div class=lepopup-cr-box&gt;&lt;input class=&#34;lepopup-checkbox lepopup-checkbox-classic lepopup-checkbox-medium&#34; type=checkbox name=lepopup-15[] id=lepopup-checkbox-HoctiquJHau3tsDy-14-0 value=on data-default=off onchange=lepopup_input_changed(this);&gt;&lt;label for=lepopup-checkbox-HoctiquJHau3tsDy-14-0 onclick=lepopup_input_error_hide(this);&gt;&lt;/label&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-cr-label lepopup-ta-left&#34;&gt;&lt;label for=lepopup-checkbox-HoctiquJHau3tsDy-14-0 onclick=lepopup_input_error_hide(this);&gt;&lt;/label&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-16 lepopup-element-html&#34; data-type=html data-top=344 data-left=338 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:515;top:344px;left:338px;width:350px;height:5px;&gt;&lt;div class=lepopup-element-html-content&gt;I agree to the &lt;a href=https://www.javacodegeeks.com/about/terms-of-use target=_blank&gt;Terms&lt;/a&gt; and &lt;a href=https://www.javacodegeeks.com/about/privacy-policy target=_blank&gt;Privacy Policy&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-17&#34; data-type=button data-top=372 data-left=308 data-animation-in=bounceIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:516;top:372px;left:308px;width:85px;height:37px;&gt;&lt;a class=&#34;lepopup-button lepopup-button-zoom-out&#34; href=https://www.javacodegeeks.com/feed/ onclick=&#34;return lepopup_submit(this);&#34; data-label=&#34;Sign up&#34; data-loading=Loading...&gt;&lt;span&gt;Sign up&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-19 lepopup-element-html&#34; data-type=html data-top=67 data-left=-15 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:518;top:67px;left:-15px;width:320px;height:363px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2015/01/books_promo.png fetchpriority=high decoding=async data-src=https://www.javacodegeeks.com/wp-content/uploads/2015/01/books_promo.png alt width=320 height=363&gt;&lt;noscript&gt;&lt;img fetchpriority=high decoding=async src=https://www.javacodegeeks.com/wp-content/uploads/2015/01/books_promo.png alt width=320 height=363&gt;&lt;/noscript&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-form lepopup-form-60 lepopup-form-G1tq3YAxHwpQPxQk lepopup-form-icon-inside lepopup-form-position-middle-right&#34; data-session=0 data-id=G1tq3YAxHwpQPxQk data-form-id=60 data-slug=7lQM6oyWL5bTm5lw data-title=&#34;Under the Post Inline&#34; data-page=confirmation data-xd=off data-width=420 data-height=320 data-position=middle-right data-esc=off data-enter=on data-disable-scrollbar=off style=display:none;width:420px;height:320px; onclick=event.stopPropagation();&gt;&lt;div class=lepopup-form-inner style=width:420px;height:320px;&gt;&lt;div class=&#34;lepopup-element lepopup-element-0 lepopup-element-html&#34; data-type=html data-top=80 data-left=70 data-animation-in=bounceInDown data-animation-out=fadeOutUp style=animation-duration:1000ms;animation-delay:0ms;z-index:500;top:80px;left:70px;width:280px;height:160px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;h4 style=&#34;text-align: center; font-size: 18px; font-weight: bold;&#34;&gt;Thank you!&lt;/h4&gt;&lt;p style=&#34;text-align: center;&#34;&gt;We will contact you soon.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;input type=hidden id=lepopup-logic-G1tq3YAxHwpQPxQk value=[]&gt;&lt;/div&gt;&lt;/div&gt;&lt;div id=post-extra-info&gt;&lt;div class=theiaStickySidebar&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=clearfix&gt;&lt;/div&gt;</description>
      <author>Anatoly Krivitsky</author>
      <guid>https://www.javacodegeeks.com/building-and-testing-a-modern-java-25-spring-boot-4-0-6-backend-docker-postgresql-openapi-serenity-bdd-cucumber-and-junit-6.html</guid>
      <pubDate>Wed, 24 Jun 2026 09:08:30 +0000</pubDate>
    </item>
    <item>
      <title>HTML UIs in Spring AI MCP Servers</title>
      <link>https://www.javacodegeeks.com/html-uis-in-spring-ai-mcp-servers.html</link>
      <description>&lt;header class=entry-header-outer&gt;&lt;nav id=breadcrumb&gt;&lt;a href=https://www.javacodegeeks.com/&gt;&lt;span class=tie-icon-home aria-hidden=true&gt;&lt;/span&gt;Home&lt;/a&gt;&lt;em class=delimiter&gt;»&lt;/em&gt;&lt;a href=https://www.javacodegeeks.com/category/java&gt;Java&lt;/a&gt;&lt;em class=delimiter&gt;»&lt;/em&gt;&lt;a href=https://www.javacodegeeks.com/category/java/enterprise-java&gt;Enterprise Java&lt;/a&gt;&lt;em class=delimiter&gt;»&lt;/em&gt;&lt;span class=current&gt;HTML UIs in Spring AI MCP Servers&lt;/span&gt;&lt;/nav&gt;&lt;div class=entry-header&gt;&lt;span class=post-cat-wrap&gt;&lt;a class=&#34;post-cat tie-cat-8&#34; href=https://www.javacodegeeks.com/category/java/enterprise-java&gt;Enterprise Java&lt;/a&gt;&lt;/span&gt;&lt;h1 class=&#34;post-title entry-title&#34;&gt;HTML UIs in Spring AI MCP Servers&lt;/h1&gt;&lt;/div&gt;&lt;/header&gt;&lt;div class=&#34;entry-content entry clearfix&#34;&gt;&lt;div class=&#34;stream-item stream-item-above-post-content&#34;&gt;&lt;div class=stream-item-size&gt;&lt;div id=adngin-in-post-0 style=&#34;float:left; margin-right:20px; margin-bottom:10px; width:300px; height:274px;&#34;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Modern AI applications are evolving beyond simple text interactions. With the introduction of the Model Context Protocol (MCP), developers can expose tools, resources, and prompts that AI agents can discover and invoke dynamically. While most MCP examples focus on APIs and tool execution, there are scenarios where returning rich HTML interfaces directly from MCP servers provides a much better user experience. In this article, we’ll explore how to build an MCP Server using Spring AI, expose an HTML-based UI through MCP resources, and test the server using MCP-compatible clients.&lt;h2&gt;&lt;a name=section-1&gt;&lt;/a&gt;1. Overview&lt;/h2&gt;&lt;p&gt;The &lt;a href=https://modelcontextprotocol.io/ target=_blank rel=noopener&gt;Model Context Protocol (MCP)&lt;/a&gt; is an open standard that enables AI models to interact with external systems in a structured and secure manner. MCP servers can expose:&lt;ul&gt;&lt;li&gt;Tools for executing actions&lt;li&gt;Resources for retrieving content&lt;li&gt;Prompts for reusable AI interactions&lt;/ul&gt;&lt;p&gt;One interesting use case is embedding HTML interfaces directly within MCP resources. Instead of returning plain text, the server can provide a complete HTML page that can be rendered by MCP-aware clients, dashboards, or agent platforms. Embedding HTML UIs within MCP resources enhances the user experience by enabling rich visual presentations, interactive dashboards, embedded reports and analytics, AI-generated custom interfaces, and improved usability for enterprise applications, making AI-powered systems more intuitive, engaging, and business-friendly.&lt;h2&gt;&lt;a name=section-2&gt;&lt;/a&gt;2. Introduction to Spring AI and MCP Servers&lt;/h2&gt;&lt;h3&gt;2.1 What is Spring AI?&lt;/h3&gt;&lt;p&gt;Spring AI is the Spring ecosystem’s framework for building AI-powered applications, providing abstractions for Large Language Models (LLMs), embeddings, vector databases, prompt engineering, AI agents, and the Model Context Protocol (MCP). It enables developers to build intelligent applications using familiar Spring Boot programming patterns while maintaining portability and flexibility across multiple AI providers.&lt;h3&gt;2.2 What is an MCP Server?&lt;/h3&gt;&lt;p&gt;An MCP (Model Context Protocol) Server exposes tools, resources, and other capabilities that AI models can dynamically discover and invoke through a standardized protocol, eliminating the need for hard-coded integrations. In a typical MCP architecture, an AI Assistant communicates with an MCP Client, which interacts with an MCP Server that provides access to various tools and resources. This architecture enables seamless integration between AI applications and external systems, with the MCP server acting as a bridge that connects AI models to enterprise services, business workflows, and data sources in a consistent and extensible manner.&lt;h2&gt;&lt;a name=section-3&gt;&lt;/a&gt;3. Creating an MCP Server with Spring AI&lt;/h2&gt;&lt;h3&gt;3.1 Project Dependencies&lt;/h3&gt;&lt;p&gt;Add the following Maven dependencies:&lt;pre class=&#34;brush:xml; wrap-lines:false;&#34;&gt;&amp;lt;dependencies&amp;gt;&#xA;    &amp;lt;dependency&amp;gt;&#xA;        &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;&#xA;        &amp;lt;artifactId&amp;gt;spring-boot-starter&amp;lt;/artifactId&amp;gt;&#xA;    &amp;lt;/dependency&amp;gt;&#xA;&#xA;    &amp;lt;dependency&amp;gt;&#xA;        &amp;lt;groupId&amp;gt;org.springframework.ai&amp;lt;/groupId&amp;gt;&#xA;        &amp;lt;artifactId&amp;gt;spring-ai-starter-mcp-server-webmvc&amp;lt;/artifactId&amp;gt;&#xA;    &amp;lt;/dependency&amp;gt;&#xA;&amp;lt;/dependencies&amp;gt;&#xA;&lt;/pre&gt;&lt;p&gt;This Maven configuration adds the core dependencies required to build a Spring AI MCP server. The &lt;code&gt;spring-boot-starter&lt;/code&gt; dependency provides the foundational Spring Boot components, including auto-configuration, dependency management, and application startup support, while the &lt;code&gt;spring-ai-starter-mcp-server-webmvc&lt;/code&gt; dependency adds Spring AI’s Model Context Protocol (MCP) server capabilities on top of Spring MVC, enabling developers to create MCP-compliant servers that can expose tools, resources, and prompts for discovery and invocation by AI clients and agents.&lt;h3&gt;3.2 Application Configuration&lt;/h3&gt;&lt;p&gt;Configure the MCP server:&lt;pre class=&#34;brush:plain; wrap-lines:false;&#34;&gt;spring:&#xA;  application:&#xA;    name: html-mcp-server&#xA;&#xA;server:&#xA;  port: 8080&#xA;&#xA;spring:&#xA;  ai:&#xA;    mcp:&#xA;      server:&#xA;        name: html-ui-server&#xA;        version: 1.0.0&#xA;&lt;/pre&gt;&lt;p&gt;This configuration defines the basic settings for the Spring Boot MCP server application. The &lt;code&gt;spring.application.name&lt;/code&gt; property assigns the application name as &lt;code&gt;html-mcp-server&lt;/code&gt;, while the &lt;code&gt;server.port&lt;/code&gt; property configures the embedded web server to listen on port &lt;code&gt;8080&lt;/code&gt;. The &lt;code&gt;spring.ai.mcp.server&lt;/code&gt; section configures the MCP server metadata by specifying a server name (&lt;code&gt;html-ui-server&lt;/code&gt;) and version (&lt;code&gt;1.0.0&lt;/code&gt;), allowing MCP clients to identify and interact with the server and its exposed capabilities through the Model Context Protocol.&lt;h3&gt;3.3 Create an HTML Dashboard Resource&lt;/h3&gt;&lt;p&gt;The following component exposes an HTML dashboard as an MCP resource.&lt;div style=&#34;display:inline-block; margin: 15px 0;&#34;&gt;&lt;div id=adngin-JavaCodeGeeks_incontent_video-0 style=display:inline-block;&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;pre class=&#34;brush:java; wrap-lines:false;&#34;&gt;package com.example.mcp.resource;&#xA;&#xA;import org.springframework.stereotype.Component;&#xA;&#xA;@Component&#xA;public class DashboardResource {&#xA;&#xA;    public String getDashboardHtml() {&#xA;        return &amp;#34;&amp;#34;&amp;#34;&#xA;            &amp;lt;html&amp;gt;&#xA;            &amp;lt;head&amp;gt;&#xA;                &amp;lt;title&amp;gt;AI Dashboard&amp;lt;/title&amp;gt;&#xA;                &amp;lt;style&amp;gt;&#xA;                    body {&#xA;                        font-family: Arial, sans-serif;&#xA;                        margin: 20px;&#xA;                    }&#xA;&#xA;                    .card {&#xA;                        border: 1px solid #ddd;&#xA;                        padding: 20px;&#xA;                        margin: 10px 0;&#xA;                        border-radius: 8px;&#xA;                        width: 250px;&#xA;                    }&#xA;&#xA;                    .metric {&#xA;                        font-size: 32px;&#xA;                        font-weight: bold;&#xA;                    }&#xA;                &amp;lt;/style&amp;gt;&#xA;            &amp;lt;/head&amp;gt;&#xA;            &amp;lt;body&amp;gt;&#xA;                &amp;lt;h1&amp;gt;Welcome to MCP Dashboard&amp;lt;/h1&amp;gt;&#xA;&#xA;                &amp;lt;div class=&amp;#39;card&amp;#39;&amp;gt;&#xA;                    &amp;lt;div&amp;gt;Active Agents&amp;lt;/div&amp;gt;&#xA;                    &amp;lt;div class=&amp;#39;metric&amp;#39;&amp;gt;24&amp;lt;/div&amp;gt;&#xA;                &amp;lt;/div&amp;gt;&#xA;&#xA;                &amp;lt;div class=&amp;#39;card&amp;#39;&amp;gt;&#xA;                    &amp;lt;div&amp;gt;MCP Requests&amp;lt;/div&amp;gt;&#xA;                    &amp;lt;div class=&amp;#39;metric&amp;#39;&amp;gt;1204&amp;lt;/div&amp;gt;&#xA;                &amp;lt;/div&amp;gt;&#xA;            &amp;lt;/body&amp;gt;&#xA;            &amp;lt;/html&amp;gt;&#xA;            &amp;#34;&amp;#34;&amp;#34;;&#xA;    }&#xA;}&#xA;&lt;/pre&gt;&lt;p&gt;This class is responsible for generating the dashboard HTML and acts as the central source of the UI markup. It is annotated with &lt;code&gt;@Component&lt;/code&gt;, which makes it a Spring-managed bean, and its &lt;code&gt;getDashboardHtml()&lt;/code&gt; method returns the complete HTML page as a Java text block. The returned markup includes the page structure, title, embedded CSS styles, dashboard heading, and metric cards such as Active Agents and MCP Requests. By keeping the HTML generation in this dedicated class, the design separates UI construction from MCP tool logic, making the dashboard easier to maintain, reuse, and update in one place.&lt;h3&gt;3.4 Create an MCP Tool&lt;/h3&gt;&lt;p&gt;Spring AI allows MCP tools to be exposed using the &lt;code&gt;@Tool&lt;/code&gt; annotation.&lt;pre class=&#34;brush:java; wrap-lines:false;&#34;&gt;package com.example.mcp.tools;&#xA;&#xA;import com.example.mcp.resource.DashboardResource;&#xA;import org.springframework.ai.tool.annotation.Tool;&#xA;import org.springframework.stereotype.Service;&#xA;&#xA;@Service&#xA;public class DashboardTools {&#xA;&#xA;    private final DashboardResource dashboardResource;&#xA;&#xA;    public DashboardTools(DashboardResource dashboardResource) {&#xA;        this.dashboardResource = dashboardResource;&#xA;    }&#xA;&#xA;    @Tool(description = &amp;#34;Returns an HTML dashboard&amp;#34;)&#xA;    public String getDashboard() {&#xA;        return &amp;#34;&amp;#34;&amp;#34;&#xA;        {&#xA;          &amp;#34;contentType&amp;#34;: &amp;#34;text/html&amp;#34;,&#xA;          &amp;#34;content&amp;#34;: %s&#xA;        }&#xA;        &amp;#34;&amp;#34;&amp;#34;.formatted(toJsonString(dashboardResource.getDashboardHtml()));&#xA;    }&#xA;&#xA;    private String toJsonString(String html) {&#xA;        return &amp;#34;\&amp;#34;&amp;#34; + html&#xA;                .replace(&amp;#34;\\&amp;#34;, &amp;#34;\\\\&amp;#34;)&#xA;                .replace(&amp;#34;\&amp;#34;&amp;#34;, &amp;#34;\\\&amp;#34;&amp;#34;)&#xA;                .replace(&amp;#34;\n&amp;#34;, &amp;#34;\\n&amp;#34;)&#xA;                .replace(&amp;#34;\r&amp;#34;, &amp;#34;&amp;#34;) + &amp;#34;\&amp;#34;&amp;#34;;&#xA;    }&#xA;}&#xA;&lt;/pre&gt;&lt;p&gt;This class is responsible for exposing the dashboard through MCP as a callable tool. It is annotated with &lt;code&gt;@Service&lt;/code&gt; and receives &lt;code&gt;DashboardResource&lt;/code&gt; through constructor injection, so it does not create the HTML itself. Instead, when the &lt;code&gt;getDashboard()&lt;/code&gt; method is invoked by an MCP client, it calls &lt;code&gt;dashboardResource.getDashboardHtml()&lt;/code&gt; to fetch the HTML generated in section 3.3, then wraps that HTML inside a JSON response with &lt;code&gt;contentType&lt;/code&gt; set to &lt;code&gt;text/html&lt;/code&gt;. This makes the flow explicit: section 3.3 is responsible for producing the dashboard HTML, while section 3.4 is responsible for publishing that HTML as an MCP tool response that clients can render directly.&lt;h3&gt;3.5 Register Tool Callback Provider&lt;/h3&gt;&lt;pre class=&#34;brush:java; wrap-lines:false;&#34;&gt;package com.example.mcp.config;&#xA;&#xA;import com.example.mcp.tools.DashboardTools;&#xA;import org.springframework.ai.tool.ToolCallbackProvider;&#xA;import org.springframework.ai.tool.method.MethodToolCallbackProvider;&#xA;import org.springframework.context.annotation.Bean;&#xA;import org.springframework.context.annotation.Configuration;&#xA;&#xA;@Configuration&#xA;public class ToolConfig {&#xA;&#xA;    @Bean&#xA;    ToolCallbackProvider tools(&#xA;            DashboardTools dashboardTools) {&#xA;&#xA;        return MethodToolCallbackProvider.builder()&#xA;                .toolObjects(dashboardTools)&#xA;                .build();&#xA;    }&#xA;}&#xA;&lt;/pre&gt;&lt;p&gt;This configuration class registers the application’s MCP tools with Spring AI so they can be discovered and invoked by MCP clients. The &lt;code&gt;@Configuration&lt;/code&gt; annotation marks the class as a source of Spring bean definitions, while the &lt;code&gt;tools()&lt;/code&gt; method creates a &lt;code&gt;ToolCallbackProvider&lt;/code&gt; bean. Using &lt;code&gt;MethodToolCallbackProvider.builder()&lt;/code&gt;, the configuration scans the supplied &lt;code&gt;DashboardTools&lt;/code&gt; object for methods annotated with &lt;code&gt;@Tool&lt;/code&gt; and automatically exposes them as MCP-compatible tools. This eliminates the need for manual tool registration and allows Spring AI to manage tool discovery, invocation, and metadata generation, making the MCP server’s capabilities available to AI assistants and clients through the Model Context Protocol.&lt;h3&gt;3.6 Main Application&lt;/h3&gt;&lt;pre class=&#34;brush:java; wrap-lines:false;&#34;&gt;package com.example.mcp;&#xA;&#xA;import org.springframework.boot.SpringApplication;&#xA;import org.springframework.boot.autoconfigure.SpringBootApplication;&#xA;&#xA;@SpringBootApplication&#xA;public class HtmlMcpServerApplication {&#xA;&#xA;    public static void main(String[] args) {&#xA;        SpringApplication.run(&#xA;            HtmlMcpServerApplication.class,&#xA;            args&#xA;        );&#xA;    }&#xA;}&#xA;&lt;/pre&gt;&lt;p&gt;This class serves as the entry point for the Spring Boot MCP server application. The &lt;code&gt;@SpringBootApplication&lt;/code&gt; annotation combines component scanning, auto-configuration, and configuration support, allowing Spring Boot to automatically discover and configure application components such as MCP tools, resources, and configuration classes. The &lt;code&gt;main()&lt;/code&gt; method invokes &lt;code&gt;SpringApplication.run()&lt;/code&gt;, which initializes the Spring application context, starts the embedded web server, loads all registered beans, and activates the Spring AI MCP server infrastructure. Once the application starts successfully, MCP clients can connect to the server and access the exposed tools and resources, including the HTML dashboard functionality implemented in the application.&lt;h3&gt;3.7 Testing the MCP Server&lt;/h3&gt;&lt;p&gt;After completing the application setup and configuration, the next step is to start the Spring Boot MCP server. Spring Boot provides a simple command-line mechanism for building and launching the application, automatically initializing the embedded web server, loading all configured MCP tools and resources, and registering them with the Spring AI MCP framework.&lt;pre class=&#34;brush:plain; wrap-lines:false;&#34;&gt;mvn spring-boot:run&lt;/pre&gt;&lt;p&gt;Executing this command compiles the project, resolves the required dependencies, and starts the application. Once the server is running successfully, MCP clients can connect to it, discover the available tools, invoke the HTML dashboard functionality, and interact with the resources exposed by the MCP server.&lt;pre class=&#34;brush:plain; wrap-lines:false;&#34;&gt;Started HtmlMcpServerApplication&#xA;&#xA;MCP Server Started&#xA;Server Name: html-ui-server&#xA;Version: 1.0.0&#xA;&#xA;Listening on port 8080&#xA;&lt;/pre&gt;&lt;h4&gt;3.7.1 Verify Tool Discovery&lt;/h4&gt;&lt;p&gt;Once the MCP server is running, the first step is to verify that the server is correctly exposing its registered tools. MCP clients can discover available capabilities by sending a &lt;code&gt;tools/list&lt;/code&gt; request, which returns metadata about all tools published by the server. This allows clients and AI assistants to understand what functionality is available before invoking specific tools.&lt;pre class=&#34;brush:plain; wrap-lines:false;&#34;&gt;// ENDPOINT&#xA;http://localhost:8080/mcp&#xA;&#xA;// REQUEST&#xA;{&#xA;  &amp;#34;method&amp;#34;: &amp;#34;tools/list&amp;#34;&#xA;}&#xA;&lt;/pre&gt;&lt;p&gt;If the tool registration was successful, the server responds with a list of available tools along with their names and descriptions. In this example, the MCP server exposes a single tool named &lt;code&gt;getDashboard&lt;/code&gt;, which returns an HTML dashboard.&lt;pre class=&#34;brush:plain; wrap-lines:false;&#34;&gt;{&#xA;  &amp;#34;tools&amp;#34;: [&#xA;    {&#xA;      &amp;#34;name&amp;#34;: &amp;#34;getDashboard&amp;#34;,&#xA;      &amp;#34;description&amp;#34;: &amp;#34;Returns an HTML dashboard&amp;#34;&#xA;    }&#xA;  ]&#xA;}&#xA;&lt;/pre&gt;&lt;h4&gt;3.7.2 Invoke the Tool&lt;/h4&gt;&lt;p&gt;After discovering the available tools, an MCP client can invoke a specific tool using the &lt;code&gt;tools/call&lt;/code&gt; method. The request includes the tool name that should be executed by the MCP server.&lt;pre class=&#34;brush:plain; wrap-lines:false;&#34;&gt;// ENDPOINT&#xA;http://localhost:8080/mcp&#xA;&#xA;// REQUEST&#xA;{&#xA;  &amp;#34;method&amp;#34;: &amp;#34;tools/call&amp;#34;,&#xA;  &amp;#34;params&amp;#34;: {&#xA;    &amp;#34;name&amp;#34;: &amp;#34;getDashboard&amp;#34;&#xA;  }&#xA;}&#xA;&lt;/pre&gt;&lt;p&gt;When the request is processed, the server executes the corresponding tool method and returns its output. In this case, the response contains HTML content with a MIME type of &lt;code&gt;text/html&lt;/code&gt;, allowing MCP-compatible clients to render the dashboard directly instead of displaying plain text.&lt;pre class=&#34;brush:plain; wrap-lines:false;&#34;&gt;{&#xA;  &amp;#34;contentType&amp;#34;: &amp;#34;text/html&amp;#34;,&#xA;  &amp;#34;content&amp;#34;: &amp;#34;&amp;lt;html&amp;gt;&#xA;&amp;lt;head&amp;gt;&#xA;    &amp;lt;title&amp;gt;AI Dashboard&amp;lt;/title&amp;gt;&#xA;    &amp;lt;style&amp;gt;&#xA;        body {&#xA;            font-family: Arial, sans-serif;&#xA;            margin: 20px;&#xA;        }&#xA;&#xA;        .card {&#xA;            border: 1px solid #ddd;&#xA;            padding: 20px;&#xA;            margin: 10px 0;&#xA;            border-radius: 8px;&#xA;            width: 250px;&#xA;        }&#xA;&#xA;        .metric {&#xA;            font-size: 32px;&#xA;            font-weight: bold;&#xA;        }&#xA;    &amp;lt;/style&amp;gt;&#xA;&amp;lt;/head&amp;gt;&#xA;&amp;lt;body&amp;gt;&#xA;    &amp;lt;h1&amp;gt;Welcome to MCP Dashboard&amp;lt;/h1&amp;gt;&#xA;&#xA;    &amp;lt;div class=&amp;#39;card&amp;#39;&amp;gt;&#xA;        &amp;lt;div&amp;gt;Active Agents&amp;lt;/div&amp;gt;&#xA;        &amp;lt;div class=&amp;#39;metric&amp;#39;&amp;gt;24&amp;lt;/div&amp;gt;&#xA;    &amp;lt;/div&amp;gt;&#xA;&#xA;    &amp;lt;div class=&amp;#39;card&amp;#39;&amp;gt;&#xA;        &amp;lt;div&amp;gt;MCP Requests&amp;lt;/div&amp;gt;&#xA;        &amp;lt;div class=&amp;#39;metric&amp;#39;&amp;gt;1204&amp;lt;/div&amp;gt;&#xA;    &amp;lt;/div&amp;gt;&#xA;&amp;lt;/body&amp;gt;&#xA;&amp;lt;/html&amp;gt;&amp;#34;&#xA;}&#xA;&lt;/pre&gt;&lt;p&gt;The response contains HTML markup generated by the &lt;code&gt;getDashboard()&lt;/code&gt; tool. Since the content type is set to &lt;code&gt;text/html&lt;/code&gt;, MCP-compatible clients can render the response as a web page, displaying dashboard components such as metrics, reports, status indicators, and other visual elements. This demonstrates how MCP tools can return rich user interfaces rather than simple text responses, enabling AI-powered applications to deliver interactive and visually appealing experiences.&lt;h2&gt;&lt;a name=section-4&gt;&lt;/a&gt;4. Conclusion&lt;/h2&gt;&lt;p&gt;Spring AI significantly simplifies the development of MCP servers by providing native support for tool registration, resource exposure, and protocol integration within Spring Boot applications. Embedding HTML UIs inside MCP resources enables developers to deliver rich dashboards, reports, analytics views, and interactive business interfaces directly through MCP clients. As MCP adoption grows, combining Spring AI’s developer-friendly programming model with HTML-based interfaces offers a powerful approach for building next-generation AI applications that seamlessly blend conversational intelligence with traditional web experiences.&lt;/p&gt;&lt;style&gt;.lepopup-progress-60 div.lepopup-progress-t1&gt;div{background-color:#e0e0e0;}.lepopup-progress-60 div.lepopup-progress-t1&gt;div&gt;div{background-color:#bd4070;}.lepopup-progress-60 div.lepopup-progress-t1&gt;div&gt;div{color:#ffffff;}.lepopup-progress-60 div.lepopup-progress-t1&gt;label{color:#444444;}.lepopup-form-60, .lepopup-form-60 *, .lepopup-progress-60 {font-size:15px;color:#444444;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-signature-box span i{font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#555555;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-signature-box,.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;text&#39;],.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;email&#39;],.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;password&#39;],.lepopup-form-60 .lepopup-element div.lepopup-input select,.lepopup-form-60 .lepopup-element div.lepopup-input select option,.lepopup-form-60 .lepopup-element div.lepopup-input textarea{font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#555555;font-style:normal;text-decoration:none;text-align:left;background-color:rgba(255, 255, 255, 0.7);background-image:none;border-width:1px;border-style:solid;border-color:#cccccc;border-radius:0px;box-shadow: inset 0px 0px 15px -7px #000000;}.lepopup-form-60 .lepopup-element div.lepopup-input ::placeholder{color:#555555; opacity: 0.9;} .lepopup-form-60 .lepopup-element div.lepopup-input ::-ms-input-placeholder{color:#555555; opacity: 0.9;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect::-webkit-scrollbar-thumb{background-color:#cccccc;}.lepopup-form-60 .lepopup-element div.lepopup-input&gt;i.lepopup-icon-left, .lepopup-form-60 .lepopup-element div.lepopup-input&gt;i.lepopup-icon-right{font-size:20px;color:#444444;border-radius:0px;}.lepopup-form-60 .lepopup-element .lepopup-button,.lepopup-form-60 .lepopup-element .lepopup-button:visited{font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#ffffff;font-weight:700;font-style:normal;text-decoration:none;text-align:center;background-color:#326693;background-image:none;border-width:1px;border-style:solid;border-color:#326693;border-radius:0px;box-shadow:none;}.lepopup-form-60 .lepopup-element div.lepopup-input .lepopup-imageselect+label{border-width:1px;border-style:solid;border-color:#cccccc;border-radius:0px;box-shadow:none;}.lepopup-form-60 .lepopup-element div.lepopup-input .lepopup-imageselect+label span.lepopup-imageselect-label{font-size:15px;color:#444444;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl:checked+label:after{background-color:rgba(255, 255, 255, 0.7);}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-classic+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-fa-check+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-square+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl+label{background-color:rgba(255, 255, 255, 0.7);border-color:#cccccc;color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-square:checked+label:after{background-color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl:checked+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl+label:after{background-color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-classic+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-fa-check+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-dot+label{background-color:rgba(255, 255, 255, 0.7);border-color:#cccccc;color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-dot:checked+label:after{background-color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect&gt;input[type=&#39;checkbox&#39;]+label:hover{background-color:#bd4070;color:#ffffff;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect&gt;input[type=&#39;checkbox&#39;]:checked+label{background-color:#a93a65;color:#ffffff;}.lepopup-form-60 .lepopup-element input[type=&#39;checkbox&#39;].lepopup-tile+label, .lepopup-form-60 .lepopup-element input[type=&#39;radio&#39;].lepopup-tile+label {font-size:15px;color:#444444;font-style:normal;text-decoration:none;text-align:center;background-color:#ffffff;background-image:none;border-width:1px;border-style:solid;border-color:#cccccc;border-radius:0px;box-shadow:none;}.lepopup-form-60 .lepopup-element-error{font-size:15px;color:#ffffff;font-style:normal;text-decoration:none;text-align:left;background-color:#d9534f;background-image:none;}.lepopup-form-60 .lepopup-element-2 {background-color:rgba(226, 236, 250, 1);background-image:none;border-width:1px;border-style:solid;border-color:rgba(216, 216, 216, 1);border-radius:3px;box-shadow: 1px 1px 15px -6px #d7e1eb;}.lepopup-form-60 .lepopup-element-3 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:26px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-3 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:26px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-3 .lepopup-element-html-content {min-height:73px;}.lepopup-form-60 .lepopup-element-4 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:19px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-4 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:19px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-4 .lepopup-element-html-content {min-height:23px;}.lepopup-form-60 .lepopup-element-5 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-5 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-5 .lepopup-element-html-content {min-height:24px;}.lepopup-form-60 .lepopup-element-6 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-6 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-6 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-7 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-7 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-7 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-8 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-8 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-8 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-9 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-9 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-9 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-10 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-10 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-10 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-11 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-11 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-11 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-12 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-12 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-12 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-13 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-13 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-13 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-14 div.lepopup-input .lepopup-icon-left, .lepopup-form-60 .lepopup-element-14 div.lepopup-input .lepopup-icon-right {line-height:36px;}.lepopup-form-60 .lepopup-element-15 div.lepopup-input{height:auto;line-height:1;}.lepopup-form-60 .lepopup-element-16 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:14px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-16 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:14px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-16 .lepopup-element-html-content {min-height:5px;}.lepopup-form-60 .lepopup-element-19 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#333333;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-19 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#333333;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-19 .lepopup-element-html-content {min-height:363px;}.lepopup-form-60 .lepopup-element-0 * {font-size:15px;color:#ffffff;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-0 {font-size:15px;color:#ffffff;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:#5cb85c;background-image:none;border-width:0px;border-style:solid;border-color:#ccc;border-radius:5px;box-shadow: 1px 1px 15px -6px #000000;padding-top:40px;padding-right:40px;padding-bottom:40px;padding-left:40px;}.lepopup-form-60 .lepopup-element-0 .lepopup-element-html-content {min-height:160px;}&lt;/style&gt;&lt;div class=lepopup-inline style=&#34;margin: 0 auto;&#34;&gt;&lt;div class=&#34;lepopup-form lepopup-form-60 lepopup-form-xZUCAcbdUOZRqyhz lepopup-form-icon-inside lepopup-form-position-middle-right&#34; data-session=0 data-id=xZUCAcbdUOZRqyhz data-form-id=60 data-slug=7lQM6oyWL5bTm5lw data-title=&#34;Under the Post Inline&#34; data-page=1 data-xd=off data-width=820 data-height=430 data-position=middle-right data-esc=off data-enter=on data-disable-scrollbar=off style=display:none;width:820px;height:430px; onclick=event.stopPropagation();&gt;&lt;div class=lepopup-form-inner style=width:820px;height:430px;&gt;&lt;div class=&#34;lepopup-element lepopup-element-2 lepopup-element-rectangle&#34; data-type=rectangle data-top=0 data-left=0 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:501;top:0px;left:0px;width:820px;height:430px;&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-3 lepopup-element-html&#34; data-type=html data-top=7 data-left=10 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:502;top:7px;left:10px;width:797px;height:73px;&gt;&lt;div class=lepopup-element-html-content&gt;Do you want to know how to develop your skillset to become a &lt;span style=&#34;color: #CAB43D; text-shadow: 1px 1px #835D5D;&#34;&gt;Java Rockstar?&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-4 lepopup-element-html&#34; data-type=html data-top=83 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:503;top:83px;left:308px;width:473px;height:23px;&gt;&lt;div class=lepopup-element-html-content&gt;Subscribe to our newsletter to start Rocking &lt;span style=&#34;text-decoration: underline;&#34;&gt;right now!&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-5 lepopup-element-html&#34; data-type=html data-top=107 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:504;top:107px;left:308px;width:473px;height:24px;&gt;&lt;div class=lepopup-element-html-content&gt;To get you started we give you our best selling eBooks for &lt;span style=&#34;color:#e01404; text-shadow: 1px 1px #C99924; font-size: 15px;&#34;&gt;FREE!&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-6 lepopup-element-html&#34; data-type=html data-top=136 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:505;top:136px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;1.&lt;/span&gt; JPA Mini Book&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-7 lepopup-element-html&#34; data-type=html data-top=156 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:506;top:156px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;2.&lt;/span&gt; JVM Troubleshooting Guide&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-8 lepopup-element-html&#34; data-type=html data-top=176 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:507;top:176px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;3.&lt;/span&gt; JUnit Tutorial for Unit Testing&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-9 lepopup-element-html&#34; data-type=html data-top=196 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:508;top:196px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;4.&lt;/span&gt; Java Annotations Tutorial&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-10 lepopup-element-html&#34; data-type=html data-top=216 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:509;top:216px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;5.&lt;/span&gt; Java Interview Questions&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-11 lepopup-element-html&#34; data-type=html data-top=236 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:510;top:236px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;6.&lt;/span&gt; Spring Interview Questions&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-12 lepopup-element-html&#34; data-type=html data-top=256 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:511;top:256px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;7.&lt;/span&gt; Android UI Design&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-13 lepopup-element-html&#34; data-type=html data-top=282 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:512;top:282px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;and many more ....&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-14&#34; data-type=email data-deps data-id=14 data-top=305 data-left=308 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:513;top:305px;left:308px;width:473px;height:36px;&gt;&lt;div class=lepopup-input&gt;&lt;input type=email name=lepopup-14 class=lepopup-ta-left placeholder=&#34;Enter your e-mail...&#34; autocomplete=email data-default aria-label=&#34;Email Field&#34; oninput=lepopup_input_changed(this); onfocus=lepopup_input_error_hide(this);&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-15&#34; data-type=checkbox data-deps data-id=15 data-top=344 data-left=308 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:514;top:344px;left:308px;width:160px;&gt;&lt;div class=&#34;lepopup-input lepopup-cr-layout-1 lepopup-cr-layout-left&#34;&gt;&lt;div class=&#34;lepopup-cr-container lepopup-cr-container-medium lepopup-cr-container-left&#34;&gt;&lt;div class=lepopup-cr-box&gt;&lt;input class=&#34;lepopup-checkbox lepopup-checkbox-classic lepopup-checkbox-medium&#34; type=checkbox name=lepopup-15[] id=lepopup-checkbox-c2K3mALqxXcy3Di8-14-0 value=on data-default=off onchange=lepopup_input_changed(this);&gt;&lt;label for=lepopup-checkbox-c2K3mALqxXcy3Di8-14-0 onclick=lepopup_input_error_hide(this);&gt;&lt;/label&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-cr-label lepopup-ta-left&#34;&gt;&lt;label for=lepopup-checkbox-c2K3mALqxXcy3Di8-14-0 onclick=lepopup_input_error_hide(this);&gt;&lt;/label&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-16 lepopup-element-html&#34; data-type=html data-top=344 data-left=338 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:515;top:344px;left:338px;width:350px;height:5px;&gt;&lt;div class=lepopup-element-html-content&gt;I agree to the &lt;a href=https://www.javacodegeeks.com/about/terms-of-use target=_blank&gt;Terms&lt;/a&gt; and &lt;a href=https://www.javacodegeeks.com/about/privacy-policy target=_blank&gt;Privacy Policy&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-17&#34; data-type=button data-top=372 data-left=308 data-animation-in=bounceIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:516;top:372px;left:308px;width:85px;height:37px;&gt;&lt;a class=&#34;lepopup-button lepopup-button-zoom-out&#34; href=https://www.javacodegeeks.com/feed/ onclick=&#34;return lepopup_submit(this);&#34; data-label=&#34;Sign up&#34; data-loading=Loading...&gt;&lt;span&gt;Sign up&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-19 lepopup-element-html&#34; data-type=html data-top=67 data-left=-15 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:518;top:67px;left:-15px;width:320px;height:363px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2015/01/books_promo.png fetchpriority=high decoding=async data-src=https://www.javacodegeeks.com/wp-content/uploads/2015/01/books_promo.png alt width=320 height=363&gt;&lt;noscript&gt;&lt;img fetchpriority=high decoding=async src=https://www.javacodegeeks.com/wp-content/uploads/2015/01/books_promo.png alt width=320 height=363&gt;&lt;/noscript&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-form lepopup-form-60 lepopup-form-xZUCAcbdUOZRqyhz lepopup-form-icon-inside lepopup-form-position-middle-right&#34; data-session=0 data-id=xZUCAcbdUOZRqyhz data-form-id=60 data-slug=7lQM6oyWL5bTm5lw data-title=&#34;Under the Post Inline&#34; data-page=confirmation data-xd=off data-width=420 data-height=320 data-position=middle-right data-esc=off data-enter=on data-disable-scrollbar=off style=display:none;width:420px;height:320px; onclick=event.stopPropagation();&gt;&lt;div class=lepopup-form-inner style=width:420px;height:320px;&gt;&lt;div class=&#34;lepopup-element lepopup-element-0 lepopup-element-html&#34; data-type=html data-top=80 data-left=70 data-animation-in=bounceInDown data-animation-out=fadeOutUp style=animation-duration:1000ms;animation-delay:0ms;z-index:500;top:80px;left:70px;width:280px;height:160px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;h4 style=&#34;text-align: center; font-size: 18px; font-weight: bold;&#34;&gt;Thank you!&lt;/h4&gt;&lt;p style=&#34;text-align: center;&#34;&gt;We will contact you soon.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;input type=hidden id=lepopup-logic-xZUCAcbdUOZRqyhz value=[]&gt;&lt;/div&gt;&lt;div class=&#34;post-bottom-meta post-bottom-tags post-tags-classic&#34;&gt;&lt;div class=post-bottom-meta-title&gt;&lt;span class=tie-icon-tags aria-hidden=true&gt;&lt;/span&gt;Tags&lt;/div&gt;&lt;span class=tagcloud&gt;&lt;a href=https://www.javacodegeeks.com/tag/spring-ai rel=tag&gt;spring ai&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div id=post-extra-info&gt;&lt;div class=theiaStickySidebar&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=clearfix&gt;&lt;/div&gt;</description>
      <author>Yatin Batra</author>
      <guid>https://www.javacodegeeks.com/html-uis-in-spring-ai-mcp-servers.html</guid>
      <pubDate>Wed, 24 Jun 2026 08:22:00 +0000</pubDate>
    </item>
    <item>
      <title>Event Sourcing vs Change Data Capture (CDC): Choosing the Right Pattern</title>
      <link>https://www.javacodegeeks.com/2026/06/event-sourcing-vs-change-data-capture-cdc-choosing-the-right-pattern.html</link>
      <description>&lt;header class=entry-header-outer&gt;&lt;nav id=breadcrumb&gt;&lt;a href=https://www.javacodegeeks.com/&gt;&lt;span class=tie-icon-home aria-hidden=true&gt;&lt;/span&gt;Home&lt;/a&gt;&lt;em class=delimiter&gt;»&lt;/em&gt;&lt;a href=https://www.javacodegeeks.com/category/software-development&gt;Software Development&lt;/a&gt;&lt;em class=delimiter&gt;»&lt;/em&gt;&lt;span class=current&gt;Event Sourcing vs Change Data Capture (CDC): Choosing the Right Pattern&lt;/span&gt;&lt;/nav&gt;&lt;div class=entry-header&gt;&lt;span class=post-cat-wrap&gt;&lt;a class=&#34;post-cat tie-cat-15&#34; href=https://www.javacodegeeks.com/category/software-development&gt;Software Development&lt;/a&gt;&lt;/span&gt;&lt;h1 class=&#34;post-title entry-title&#34;&gt;Event Sourcing vs Change Data Capture (CDC): Choosing the Right Pattern&lt;/h1&gt;&lt;/div&gt;&lt;/header&gt;&lt;div class=&#34;entry-content entry clearfix&#34;&gt;&lt;div class=&#34;stream-item stream-item-above-post-content&#34;&gt;&lt;div class=stream-item-size&gt;&lt;div id=adngin-in-post-0 style=&#34;float:left; margin-right:20px; margin-bottom:10px; width:300px; height:274px;&#34;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;em&gt;Both patterns produce a stream of state changes — yet they sit at entirely different layers of your stack, solve different problems, and carry very different costs. Here is how to tell them apart and pick the right one.&lt;/em&gt;&lt;p&gt;At first glance, Event Sourcing and Change Data Capture (CDC) look like two names for the same idea: capture what changed, and send it somewhere useful. In practice, however, the two patterns differ in where they live, what guarantees they offer, and how much they will cost your team to introduce. Getting this choice wrong is expensive — Event Sourcing in particular rewrites the rules of how your application persists data, and rolling it back after the fact is rarely straightforward.&lt;p&gt;In this article, we will walk through both patterns clearly, compare them across the dimensions that actually matter in production, and end with a practical decision guide. Along the way, we will look at Java and Spring Boot examples using the tools most teams reach for: &lt;a href=https://debezium.io/ target=_blank rel=&#34;noreferrer noopener&#34;&gt;Debezium&lt;/a&gt; for CDC, and frameworks like &lt;a href=https://axoniq.io/ target=_blank rel=&#34;noreferrer noopener&#34;&gt;Axon&lt;/a&gt; or &lt;a href=https://www.eventstore.com/ target=_blank rel=&#34;noreferrer noopener&#34;&gt;EventStoreDB&lt;/a&gt; for Event Sourcing.&lt;h2 class=wp-block-heading&gt;What Is Event Sourcing?&lt;/h2&gt;&lt;p&gt;Event Sourcing is an &lt;strong&gt;application-level design pattern&lt;/strong&gt;. Instead of persisting only the current state of an entity — the usual row in a relational table — the application records every change that happened to that entity as an immutable event. The current state is then derived by replaying those events in order.&lt;p&gt;Think about a bank account. In a traditional CRUD model, you store the current balance and overwrite it on every transaction. With Event Sourcing, you instead append events like &lt;code&gt;MoneyDeposited(amount=500)&lt;/code&gt; and &lt;code&gt;MoneyWithdrawn(amount=200)&lt;/code&gt;. To find the current balance, you fold those events from the beginning — or from the latest snapshot.&lt;pre class=brush:java&gt;// Axon Framework — a simple event-sourced aggregate in Spring Boot&#xA;@Aggregate&#xA;public class BankAccount {&#xA;&#xA;    @AggregateIdentifier&#xA;    private String accountId;&#xA;    private BigDecimal balance;&#xA;&#xA;    @CommandHandler&#xA;    public BankAccount(OpenAccountCommand cmd) {&#xA;        apply(new AccountOpenedEvent(cmd.getAccountId(), cmd.getInitialDeposit()));&#xA;    }&#xA;&#xA;    @EventSourcingHandler&#xA;    public void on(AccountOpenedEvent event) {&#xA;        this.accountId = event.getAccountId();&#xA;        this.balance   = event.getInitialDeposit();&#xA;    }&#xA;&#xA;    @CommandHandler&#xA;    public void handle(DepositMoneyCommand cmd) {&#xA;        apply(new MoneyDepositedEvent(accountId, cmd.getAmount()));&#xA;    }&#xA;&#xA;    @EventSourcingHandler&#xA;    public void on(MoneyDepositedEvent event) {&#xA;        this.balance = this.balance.add(event.getAmount());&#xA;    }&#xA;}&#xA;&lt;/pre&gt;&lt;p&gt;Notice that the aggregate never calls &lt;code&gt;save()&lt;/code&gt;. The events themselves are the source of truth, and the event store is the primary database. This is what distinguishes Event Sourcing from simply publishing domain events alongside a CRUD persist — in Event Sourcing the event &lt;em&gt;is&lt;/em&gt; the persistence.&lt;blockquote class=&#34;wp-block-quote is-layout-flow wp-block-quote-is-layout-flow&#34;&gt;&lt;p&gt;As the event log grows, replaying from the beginning becomes slow. The snapshot pattern periodically saves the current state so consumers can start from the latest snapshot and replay only subsequent events. Most Event Sourcing frameworks include this out of the box.&lt;/blockquote&gt;&lt;h2 class=wp-block-heading&gt;What Is Change Data Capture?&lt;/h2&gt;&lt;p&gt;Change Data Capture is a &lt;strong&gt;database-level technique&lt;/strong&gt;. It monitors the transaction log of an existing database — PostgreSQL’s WAL, MySQL’s binlog, MongoDB’s oplog — and emits a structured event for every row-level insert, update, or delete. Crucially, the application does not need to be aware of any of this. It keeps writing to its tables exactly as before, and the CDC connector reads the change events externally.&lt;p&gt;&lt;a href=https://debezium.io/ target=_blank rel=&#34;noreferrer noopener&#34;&gt;Debezium&lt;/a&gt; is the most widely adopted open-source CDC tool in the Java ecosystem. It runs as a Kafka Connect connector and streams change events to Kafka topics, which downstream services can then consume in real time.&lt;pre class=brush:js&gt;# Debezium PostgreSQL connector configuration (connector.json)&#xA;# Deploy via Kafka Connect REST API:&#xA;# POST http://localhost:8083/connectors&#xA;{&#xA;  &amp;#34;name&amp;#34;: &amp;#34;pg-orders-connector&amp;#34;,&#xA;  &amp;#34;config&amp;#34;: {&#xA;    &amp;#34;connector.class&amp;#34;:              &amp;#34;io.debezium.connector.postgresql.PostgresConnector&amp;#34;,&#xA;    &amp;#34;database.hostname&amp;#34;:            &amp;#34;localhost&amp;#34;,&#xA;    &amp;#34;database.port&amp;#34;:                &amp;#34;5432&amp;#34;,&#xA;    &amp;#34;database.user&amp;#34;:                &amp;#34;debezium&amp;#34;,&#xA;    &amp;#34;database.password&amp;#34;:            &amp;#34;dbz&amp;#34;,&#xA;    &amp;#34;database.dbname&amp;#34;:              &amp;#34;shop&amp;#34;,&#xA;    &amp;#34;topic.prefix&amp;#34;:                 &amp;#34;shop&amp;#34;,&#xA;    &amp;#34;table.include.list&amp;#34;:           &amp;#34;public.orders&amp;#34;,&#xA;    &amp;#34;plugin.name&amp;#34;:                  &amp;#34;pgoutput&amp;#34;&#xA;  }&#xA;}&#xA;&lt;/pre&gt;&lt;p&gt;Once that connector is running, every change to the &lt;code&gt;orders&lt;/code&gt; table is automatically published to the Kafka topic &lt;code&gt;shop.public.orders&lt;/code&gt; as a structured event containing both the &lt;code&gt;before&lt;/code&gt; and &lt;code&gt;after&lt;/code&gt; state of the row. Downstream consumers — an analytics service, a search indexer, an audit log — subscribe to that topic and react accordingly.&lt;blockquote class=&#34;wp-block-quote is-layout-flow wp-block-quote-is-layout-flow&#34;&gt;&lt;p&gt;A single business action — say, “transfer $100 from account A to account B” — may produce several CDC events: a debit on one row, a credit on another, a transfer record insert. CDC sees the rows; it does not inherently understand the business transaction that caused them.&lt;/blockquote&gt;&lt;h2 class=wp-block-heading&gt;The Fundamental Difference&lt;/h2&gt;&lt;p&gt;The cleanest way to state the core distinction is this:&lt;div style=&#34;display:inline-block; margin: 15px 0;&#34;&gt;&lt;div id=adngin-JavaCodeGeeks_incontent_video-0 style=display:inline-block;&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;h4 class=wp-block-heading&gt;Event Sourcing&lt;/h4&gt;&lt;ul class=wp-block-list&gt;&lt;li&gt;Events are written &lt;em&gt;by the application&lt;/em&gt;&lt;li&gt;Events are the &lt;strong&gt;primary persistence&lt;/strong&gt;&lt;li&gt;Current state is derived &lt;em&gt;from&lt;/em&gt; events&lt;li&gt;Domain semantics are baked into event names&lt;li&gt;Requires redesigning your data model&lt;/ul&gt;&lt;h4 class=wp-block-heading&gt;Change Data Capture&lt;/h4&gt;&lt;ul class=wp-block-list&gt;&lt;li&gt;Events are read &lt;em&gt;from the database log&lt;/em&gt;&lt;li&gt;Database state is still &lt;strong&gt;primary&lt;/strong&gt;&lt;li&gt;Events are derived &lt;em&gt;from&lt;/em&gt; database writes&lt;li&gt;Events carry row-level, not domain-level, semantics&lt;li&gt;Zero application changes required&lt;/ul&gt;&lt;p&gt;As &lt;a href=https://streamkap.com/resources-and-guides/event-sourcing-cdc target=_blank rel=&#34;noreferrer noopener&#34;&gt;Streamkap puts it well&lt;/a&gt;: in true Event Sourcing, events are the primary artifact and database state is derived. With CDC, database state is primary and events are derived. That reversal of cause and effect explains nearly every practical difference between the two.&lt;h2 class=wp-block-heading&gt;Side-by-Side Comparison&lt;/h2&gt;&lt;figure class=wp-block-table&gt;&lt;table class=has-fixed-layout&gt;&lt;thead&gt;&lt;tr&gt;&lt;th class=has-text-align-left data-align=left&gt;Dimension&lt;th class=has-text-align-left data-align=left&gt;Event Sourcing&lt;th class=has-text-align-left data-align=left&gt;CDC (e.g. Debezium)&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Where it lives&lt;/strong&gt;&lt;td&gt;Application layer&lt;td&gt;Database / infrastructure layer&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Application changes needed&lt;/strong&gt;&lt;td&gt;Yes — significant redesign&lt;td&gt;No — transparent to app&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Event semantics&lt;/strong&gt;&lt;td&gt;Rich domain events (&lt;code&gt;OrderShipped&lt;/code&gt;)&lt;td&gt;Raw data changes (&lt;code&gt;UPDATE orders SET status=&amp;#39;shipped&amp;#39;&lt;/code&gt;)&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Full history replay&lt;/strong&gt;&lt;td&gt;Yes — events are the store&lt;td&gt;Limited by log retention&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Audit trail quality&lt;/strong&gt;&lt;td&gt;Excellent — intent is captured&lt;td&gt;Good — data changes only&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Retroactive migration&lt;/strong&gt;&lt;td&gt;Very hard on existing systems&lt;td&gt;Easy to bolt on existing systems&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Operational complexity&lt;/strong&gt;&lt;td&gt;High&lt;td&gt;Medium&lt;tr&gt;&lt;td&gt;&lt;strong&gt;CQRS compatibility&lt;/strong&gt;&lt;td&gt;Natural fit&lt;td&gt;Works well with Outbox pattern&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Typical tooling (Java)&lt;/strong&gt;&lt;td&gt;Axon, EventStoreDB, Eventuate&lt;td&gt;Debezium + Kafka Connect&lt;/table&gt;&lt;/figure&gt;&lt;h2 class=wp-block-heading&gt;The Outbox Pattern: Bridging Both Worlds&lt;/h2&gt;&lt;p&gt;One of the most practically useful combinations is running CDC on top of an &lt;strong&gt;Outbox table&lt;/strong&gt;. This is where the two patterns genuinely complement each other, and it is increasingly the recommended approach for teams who need domain event semantics without fully committing to an Event Sourcing data model.&lt;p&gt;The idea is straightforward: your application writes its domain events into a dedicated &lt;code&gt;outbox&lt;/code&gt; table as part of the same database transaction that updates the primary state. A CDC connector then reads that outbox table and publishes the events to Kafka. The result is domain-semantic events with transactional guarantees — and no dual-write problem.&lt;pre class=brush:sql&gt;-- The outbox table in PostgreSQL&#xA;CREATE TABLE outbox_events (&#xA;    id            UUID PRIMARY KEY DEFAULT gen_random_uuid(),&#xA;    aggregate_id  VARCHAR(255) NOT NULL,&#xA;    event_type    VARCHAR(255) NOT NULL,&#xA;    payload       JSONB         NOT NULL,&#xA;    created_at    TIMESTAMPTZ   NOT NULL DEFAULT NOW()&#xA;);&#xA;&#xA;-- In your Spring service: both writes in one transaction&#xA;@Transactional&#xA;public void shipOrder(Long orderId) {&#xA;    Order order = orderRepo.findById(orderId).orElseThrow();&#xA;    order.setStatus(&amp;#34;SHIPPED&amp;#34;);&#xA;    orderRepo.save(order);&#xA;&#xA;    outboxRepo.save(new OutboxEvent(&#xA;        order.getId().toString(),&#xA;        &amp;#34;OrderShipped&amp;#34;,&#xA;        &amp;#34;{\&amp;#34;orderId\&amp;#34;:&amp;#34; + orderId + &amp;#34;,\&amp;#34;shippedAt\&amp;#34;:\&amp;#34;&amp;#34; + Instant.now() + &amp;#34;\&amp;#34;}&amp;#34;&#xA;    ));&#xA;    // Debezium picks up the outbox row and publishes to Kafka automatically&#xA;}&#xA;&lt;/pre&gt;&lt;p&gt;Debezium even ships an &lt;a href=https://debezium.io/documentation/reference/transformations/outbox-event-router.html target=_blank rel=&#34;noreferrer noopener&#34;&gt;Outbox Event Router&lt;/a&gt; transform that routes events to different Kafka topics based on the &lt;code&gt;aggregate_id&lt;/code&gt; or &lt;code&gt;event_type&lt;/code&gt; columns, so you do not end up with a single firehose topic for all events.&lt;blockquote class=&#34;wp-block-quote is-layout-flow wp-block-quote-is-layout-flow&#34;&gt;&lt;p&gt;It gives you domain-semantic events and at-least-once delivery with no distributed transaction, no dual-write race condition, and no application-level retry logic. For most microservice architectures, this is simpler than full Event Sourcing while delivering most of the same downstream benefits.&lt;/blockquote&gt;&lt;h2 class=wp-block-heading&gt;Comparing Complexity Over Time&lt;/h2&gt;&lt;p&gt;One chart worth looking at is how each approach’s operational complexity evolves as a system grows. Event Sourcing starts expensive and stays demanding; CDC starts cheap but can accumulate complexity as your schema and event consumer count scales.&lt;p class=has-text-align-center&gt;&lt;strong&gt;Relative Operational Complexity by System Scale&lt;/strong&gt;&lt;div class=wp-block-image&gt;&lt;figure class=&#34;aligncenter size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-19_21-13-35.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-19_21-13-35.png fetchpriority=high decoding=async width=504 height=276 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-19_21-13-35.png alt class=wp-image-144089 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-19_21-13-35.png 504w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-19_21-13-35-300x164.png 300w&#34; data-sizes=&#34;(max-width: 504px) 100vw, 504px&#34;&gt;&lt;noscript&gt;&lt;img fetchpriority=high decoding=async width=504 height=276 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-19_21-13-35.png alt class=wp-image-144089 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-19_21-13-35.png 504w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-19_21-13-35-300x164.png 300w&#34; sizes=&#34;(max-width: 504px) 100vw, 504px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;figcaption class=wp-element-caption&gt;Illustrative complexity scores (1–10) at five growth stages. Based on reported engineering effort across documented production cases.&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&lt;h2 class=wp-block-heading&gt;When to Choose Event Sourcing&lt;/h2&gt;&lt;p&gt;Event Sourcing is a strong fit when the &lt;em&gt;history of intent&lt;/em&gt; is a first-class requirement — not just “what changed” but “why, in what sequence, and who requested it.” However, it imposes real costs, so the use case needs to justify the redesign.&lt;h4 class=wp-block-heading&gt;Choose Event Sourcing when…&lt;/h4&gt;&lt;ul class=wp-block-list&gt;&lt;li&gt;You need a complete, tamper-evident audit trail — legal, financial, or compliance scenarios where the sequence of decisions matters.&lt;li&gt;Your domain logic involves temporal queries: “what was the state of this entity on this date?”&lt;li&gt;You are building a new greenfield service and the team is comfortable with CQRS and event-driven design.&lt;li&gt;Business events carry rich semantic meaning that CDC row events cannot capture (&lt;code&gt;ClaimApproved&lt;/code&gt; vs &lt;code&gt;UPDATE claims SET approved=true&lt;/code&gt;).&lt;li&gt;You need the ability to correct past events and reproject read models — event replay is a first-class feature.&lt;/ul&gt;&lt;h2 class=wp-block-heading&gt;When to Choose CDC&lt;/h2&gt;&lt;p&gt;CDC shines in integration and data propagation scenarios, especially when you need to connect systems that already exist and cannot be rewritten. Because it requires zero application changes, it is also the most pragmatic choice for teams that want event-driven integration without taking on architectural debt.&lt;h4 class=wp-block-heading&gt;Choose CDC when…&lt;/h4&gt;&lt;ul class=wp-block-list&gt;&lt;li&gt;You need to replicate data from an existing CRUD service to downstream consumers (analytics warehouse, search index, caching layer) without changing that service.&lt;li&gt;You are retrofitting event-driven patterns onto a legacy system.&lt;li&gt;Your team is comfortable with Kafka and Kafka Connect but not ready for a full Event Sourcing architecture.&lt;li&gt;Data synchronization and replication are the primary goals, and row-level semantics are sufficient.&lt;li&gt;You want to implement the Outbox pattern to guarantee event delivery without dual-write complexity.&lt;/ul&gt;&lt;h2 class=wp-block-heading&gt;When to Use Both Together&lt;/h2&gt;&lt;h4 class=wp-block-heading&gt;Use both when…&lt;/h4&gt;&lt;ul class=wp-block-list&gt;&lt;li&gt;Event-sourced aggregates need to propagate their events to external systems — CDC on the event store’s projection tables bridges the gap.&lt;li&gt;A system has both greenfield event-sourced services and legacy CRUD services that must share a single event bus.&lt;li&gt;You want domain events from the Outbox pattern with CDC providing the reliable transport layer.&lt;/ul&gt;&lt;h2 class=wp-block-heading&gt;Tooling Landscape for Java Teams&lt;/h2&gt;&lt;figure class=wp-block-table&gt;&lt;table class=has-fixed-layout&gt;&lt;thead&gt;&lt;tr&gt;&lt;th class=has-text-align-left data-align=left&gt;Tool&lt;th class=has-text-align-left data-align=left&gt;Pattern&lt;th class=has-text-align-left data-align=left&gt;Spring Boot Integration&lt;th class=has-text-align-left data-align=left&gt;Notes&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a href=https://debezium.io/ target=_blank rel=&#34;noreferrer noopener&#34;&gt;Debezium&lt;/a&gt;&lt;td&gt;CDC&lt;td&gt;Spring Cloud Stream, Kafka Connect&lt;td&gt;Most mature open-source CDC; supports PostgreSQL, MySQL, MongoDB, Oracle and more&lt;tr&gt;&lt;td&gt;&lt;a href=https://axoniq.io/ target=_blank rel=&#34;noreferrer noopener&#34;&gt;Axon Framework&lt;/a&gt;&lt;td&gt;Event Sourcing&lt;td&gt;Native Spring Boot starter&lt;td&gt;Full CQRS + Event Sourcing framework; pairs with Axon Server as event store&lt;tr&gt;&lt;td&gt;&lt;a href=https://www.eventstore.com/ target=_blank rel=&#34;noreferrer noopener&#34;&gt;EventStoreDB&lt;/a&gt;&lt;td&gt;Event Sourcing&lt;td&gt;Via Java client library&lt;td&gt;Purpose-built event store; strong projections support&lt;tr&gt;&lt;td&gt;&lt;a href=https://eventuate.io/ target=_blank rel=&#34;noreferrer noopener&#34;&gt;Eventuate Tram&lt;/a&gt;&lt;td&gt;Outbox + CDC&lt;td&gt;Spring Boot starter available&lt;td&gt;Specifically designed around the Transactional Outbox pattern with CDC&lt;tr&gt;&lt;td&gt;Kafka + Custom Outbox&lt;td&gt;Outbox + CDC&lt;td&gt;Spring Kafka, spring-tx&lt;td&gt;Maximum control; higher setup cost&lt;/table&gt;&lt;/figure&gt;&lt;h2 class=wp-block-heading&gt;Adoption Trends: Where Teams Are Investing&lt;/h2&gt;&lt;p&gt;Based on community signals — GitHub stars, conference talks, and job postings — it is clear that CDC and the Outbox pattern have significantly broader adoption among Java teams than full Event Sourcing. Event Sourcing remains the right choice in specific bounded contexts, but it is rarely the default starting point for new services.&lt;p class=has-text-align-center&gt;&lt;strong&gt;Relative Adoption Signal Across Java Ecosystem (2024–2025)&lt;/strong&gt;&lt;div class=wp-block-image&gt;&lt;figure class=&#34;aligncenter size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-19_21-14-26.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-19_21-14-26.png decoding=async width=506 height=266 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-19_21-14-26.png alt class=wp-image-144090 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-19_21-14-26.png 506w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-19_21-14-26-300x158.png 300w&#34; data-sizes=&#34;(max-width: 506px) 100vw, 506px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=506 height=266 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-19_21-14-26.png alt class=wp-image-144090 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-19_21-14-26.png 506w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-19_21-14-26-300x158.png 300w&#34; sizes=&#34;(max-width: 506px) 100vw, 506px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;figcaption class=wp-element-caption&gt;Normalized index based on GitHub stars, conference talks, and StackOverflow activity. Higher = more community momentum.&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&lt;h2 class=wp-block-heading&gt;A Quick Decision Tree&lt;/h2&gt;&lt;p&gt;If you are still unsure which path to take, the following set of questions will usually narrow it down quickly:&lt;ol class=wp-block-list&gt;&lt;li&gt;&lt;strong&gt;Do you need to derive business intent from the events?&lt;/strong&gt; If yes and the system is new → Event Sourcing. If yes and the system is existing → Outbox + CDC.&lt;li&gt;&lt;strong&gt;Are you integrating with existing services you cannot change?&lt;/strong&gt; → CDC.&lt;li&gt;&lt;strong&gt;Is the audit trail a legal or compliance requirement?&lt;/strong&gt; If intent matters → Event Sourcing. If data changes are sufficient → CDC.&lt;li&gt;&lt;strong&gt;Does your team have event-driven architecture experience?&lt;/strong&gt; If not → start with CDC and the Outbox pattern; it is significantly easier to introduce.&lt;li&gt;&lt;strong&gt;Are you building a new greenfield bounded context where history replay is a first-class feature?&lt;/strong&gt; → Event Sourcing is a strong candidate.&lt;li&gt;&lt;/ol&gt;&lt;blockquote class=&#34;wp-block-quote is-layout-flow wp-block-quote-is-layout-flow&#34;&gt;&lt;p&gt;The engineers behind Debezium have &lt;a href=https://debezium.io/blog/2020/02/10/event-sourcing-vs-cdc/ target=_blank rel=&#34;noreferrer noopener&#34;&gt;written directly about this&lt;/a&gt;: CDC with the Outbox pattern is usually a better alternative to full Event Sourcing and is compatible with CQRS. Event Sourcing still has value in some use cases, but they encourage trying the Outbox approach first.&lt;/blockquote&gt;&lt;h2 class=wp-block-heading&gt;What We Learned&lt;/h2&gt;&lt;p&gt;Event Sourcing and CDC are not competing solutions to the same problem — they operate at entirely different layers of a system. Event Sourcing is an application design pattern where events are the primary persistence artifact, giving you rich domain semantics, full replay capability, and a complete audit trail of intent. CDC is a database infrastructure technique that reads the transaction log and streams row-level changes to downstream consumers, requiring zero application changes and fitting naturally onto existing CRUD systems.&lt;p&gt;For most Java teams, CDC with the Transactional Outbox pattern is the pragmatic starting point: you get at-least-once event delivery, domain-semantic events, and no dual-write problem — without the significant architectural cost of fully embracing Event Sourcing. Event Sourcing earns its keep in greenfield bounded contexts where temporal queries, complete audit trails, and event replay are genuine requirements, not just aspirational ones. When in doubt, reach for Debezium and an Outbox table first, and layer Event Sourcing into specific aggregates only where the domain truly demands it.&lt;/p&gt;&lt;style&gt;.lepopup-progress-60 div.lepopup-progress-t1&gt;div{background-color:#e0e0e0;}.lepopup-progress-60 div.lepopup-progress-t1&gt;div&gt;div{background-color:#bd4070;}.lepopup-progress-60 div.lepopup-progress-t1&gt;div&gt;div{color:#ffffff;}.lepopup-progress-60 div.lepopup-progress-t1&gt;label{color:#444444;}.lepopup-form-60, .lepopup-form-60 *, .lepopup-progress-60 {font-size:15px;color:#444444;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-signature-box span i{font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#555555;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-signature-box,.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;text&#39;],.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;email&#39;],.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;password&#39;],.lepopup-form-60 .lepopup-element div.lepopup-input select,.lepopup-form-60 .lepopup-element div.lepopup-input select option,.lepopup-form-60 .lepopup-element div.lepopup-input textarea{font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#555555;font-style:normal;text-decoration:none;text-align:left;background-color:rgba(255, 255, 255, 0.7);background-image:none;border-width:1px;border-style:solid;border-color:#cccccc;border-radius:0px;box-shadow: inset 0px 0px 15px -7px #000000;}.lepopup-form-60 .lepopup-element div.lepopup-input ::placeholder{color:#555555; opacity: 0.9;} .lepopup-form-60 .lepopup-element div.lepopup-input ::-ms-input-placeholder{color:#555555; opacity: 0.9;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect::-webkit-scrollbar-thumb{background-color:#cccccc;}.lepopup-form-60 .lepopup-element div.lepopup-input&gt;i.lepopup-icon-left, .lepopup-form-60 .lepopup-element div.lepopup-input&gt;i.lepopup-icon-right{font-size:20px;color:#444444;border-radius:0px;}.lepopup-form-60 .lepopup-element .lepopup-button,.lepopup-form-60 .lepopup-element .lepopup-button:visited{font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#ffffff;font-weight:700;font-style:normal;text-decoration:none;text-align:center;background-color:#326693;background-image:none;border-width:1px;border-style:solid;border-color:#326693;border-radius:0px;box-shadow:none;}.lepopup-form-60 .lepopup-element div.lepopup-input .lepopup-imageselect+label{border-width:1px;border-style:solid;border-color:#cccccc;border-radius:0px;box-shadow:none;}.lepopup-form-60 .lepopup-element div.lepopup-input .lepopup-imageselect+label span.lepopup-imageselect-label{font-size:15px;color:#444444;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl:checked+label:after{background-color:rgba(255, 255, 255, 0.7);}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-classic+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-fa-check+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-square+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl+label{background-color:rgba(255, 255, 255, 0.7);border-color:#cccccc;color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-square:checked+label:after{background-color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl:checked+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl+label:after{background-color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-classic+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-fa-check+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-dot+label{background-color:rgba(255, 255, 255, 0.7);border-color:#cccccc;color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-dot:checked+label:after{background-color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect&gt;input[type=&#39;checkbox&#39;]+label:hover{background-color:#bd4070;color:#ffffff;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect&gt;input[type=&#39;checkbox&#39;]:checked+label{background-color:#a93a65;color:#ffffff;}.lepopup-form-60 .lepopup-element input[type=&#39;checkbox&#39;].lepopup-tile+label, .lepopup-form-60 .lepopup-element input[type=&#39;radio&#39;].lepopup-tile+label {font-size:15px;color:#444444;font-style:normal;text-decoration:none;text-align:center;background-color:#ffffff;background-image:none;border-width:1px;border-style:solid;border-color:#cccccc;border-radius:0px;box-shadow:none;}.lepopup-form-60 .lepopup-element-error{font-size:15px;color:#ffffff;font-style:normal;text-decoration:none;text-align:left;background-color:#d9534f;background-image:none;}.lepopup-form-60 .lepopup-element-2 {background-color:rgba(226, 236, 250, 1);background-image:none;border-width:1px;border-style:solid;border-color:rgba(216, 216, 216, 1);border-radius:3px;box-shadow: 1px 1px 15px -6px #d7e1eb;}.lepopup-form-60 .lepopup-element-3 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:26px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-3 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:26px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-3 .lepopup-element-html-content {min-height:73px;}.lepopup-form-60 .lepopup-element-4 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:19px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-4 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:19px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-4 .lepopup-element-html-content {min-height:23px;}.lepopup-form-60 .lepopup-element-5 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-5 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-5 .lepopup-element-html-content {min-height:24px;}.lepopup-form-60 .lepopup-element-6 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-6 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-6 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-7 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-7 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-7 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-8 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-8 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-8 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-9 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-9 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-9 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-10 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-10 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-10 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-11 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-11 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-11 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-12 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-12 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-12 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-13 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-13 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-13 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-14 div.lepopup-input .lepopup-icon-left, .lepopup-form-60 .lepopup-element-14 div.lepopup-input .lepopup-icon-right {line-height:36px;}.lepopup-form-60 .lepopup-element-15 div.lepopup-input{height:auto;line-height:1;}.lepopup-form-60 .lepopup-element-16 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:14px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-16 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:14px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-16 .lepopup-element-html-content {min-height:5px;}.lepopup-form-60 .lepopup-element-19 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#333333;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-19 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#333333;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-19 .lepopup-element-html-content {min-height:363px;}.lepopup-form-60 .lepopup-element-0 * {font-size:15px;color:#ffffff;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-0 {font-size:15px;color:#ffffff;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:#5cb85c;background-image:none;border-width:0px;border-style:solid;border-color:#ccc;border-radius:5px;box-shadow: 1px 1px 15px -6px #000000;padding-top:40px;padding-right:40px;padding-bottom:40px;padding-left:40px;}.lepopup-form-60 .lepopup-element-0 .lepopup-element-html-content {min-height:160px;}&lt;/style&gt;&lt;div class=lepopup-inline style=&#34;margin: 0 auto;&#34;&gt;&lt;div class=&#34;lepopup-form lepopup-form-60 lepopup-form-kJX2DRnnDmSFHrad lepopup-form-icon-inside lepopup-form-position-middle-right&#34; data-session=0 data-id=kJX2DRnnDmSFHrad data-form-id=60 data-slug=7lQM6oyWL5bTm5lw data-title=&#34;Under the Post Inline&#34; data-page=1 data-xd=off data-width=820 data-height=430 data-position=middle-right data-esc=off data-enter=on data-disable-scrollbar=off style=display:none;width:820px;height:430px; onclick=event.stopPropagation();&gt;&lt;div class=lepopup-form-inner style=width:820px;height:430px;&gt;&lt;div class=&#34;lepopup-element lepopup-element-2 lepopup-element-rectangle&#34; data-type=rectangle data-top=0 data-left=0 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:501;top:0px;left:0px;width:820px;height:430px;&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-3 lepopup-element-html&#34; data-type=html data-top=7 data-left=10 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:502;top:7px;left:10px;width:797px;height:73px;&gt;&lt;div class=lepopup-element-html-content&gt;Do you want to know how to develop your skillset to become a &lt;span style=&#34;color: #CAB43D; text-shadow: 1px 1px #835D5D;&#34;&gt;Java Rockstar?&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-4 lepopup-element-html&#34; data-type=html data-top=83 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:503;top:83px;left:308px;width:473px;height:23px;&gt;&lt;div class=lepopup-element-html-content&gt;Subscribe to our newsletter to start Rocking &lt;span style=&#34;text-decoration: underline;&#34;&gt;right now!&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-5 lepopup-element-html&#34; data-type=html data-top=107 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:504;top:107px;left:308px;width:473px;height:24px;&gt;&lt;div class=lepopup-element-html-content&gt;To get you started we give you our best selling eBooks for &lt;span style=&#34;color:#e01404; text-shadow: 1px 1px #C99924; font-size: 15px;&#34;&gt;FREE!&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-6 lepopup-element-html&#34; data-type=html data-top=136 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:505;top:136px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;1.&lt;/span&gt; JPA Mini Book&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-7 lepopup-element-html&#34; data-type=html data-top=156 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:506;top:156px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;2.&lt;/span&gt; JVM Troubleshooting Guide&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-8 lepopup-element-html&#34; data-type=html data-top=176 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:507;top:176px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;3.&lt;/span&gt; JUnit Tutorial for Unit Testing&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-9 lepopup-element-html&#34; data-type=html data-top=196 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:508;top:196px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;4.&lt;/span&gt; Java Annotations Tutorial&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-10 lepopup-element-html&#34; data-type=html data-top=216 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:509;top:216px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;5.&lt;/span&gt; Java Interview Questions&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-11 lepopup-element-html&#34; data-type=html data-top=236 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:510;top:236px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;6.&lt;/span&gt; Spring Interview Questions&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-12 lepopup-element-html&#34; data-type=html data-top=256 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:511;top:256px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;7.&lt;/span&gt; Android UI Design&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-13 lepopup-element-html&#34; data-type=html data-top=282 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:512;top:282px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;and many more ....&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-14&#34; data-type=email data-deps data-id=14 data-top=305 data-left=308 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:513;top:305px;left:308px;width:473px;height:36px;&gt;&lt;div class=lepopup-input&gt;&lt;input type=email name=lepopup-14 class=lepopup-ta-left placeholder=&#34;Enter your e-mail...&#34; autocomplete=email data-default aria-label=&#34;Email Field&#34; oninput=lepopup_input_changed(this); onfocus=lepopup_input_error_hide(this);&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-15&#34; data-type=checkbox data-deps data-id=15 data-top=344 data-left=308 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:514;top:344px;left:308px;width:160px;&gt;&lt;div class=&#34;lepopup-input lepopup-cr-layout-1 lepopup-cr-layout-left&#34;&gt;&lt;div class=&#34;lepopup-cr-container lepopup-cr-container-medium lepopup-cr-container-left&#34;&gt;&lt;div class=lepopup-cr-box&gt;&lt;input class=&#34;lepopup-checkbox lepopup-checkbox-classic lepopup-checkbox-medium&#34; type=checkbox name=lepopup-15[] id=lepopup-checkbox-55BvwfRLSrYMjmHz-14-0 value=on data-default=off onchange=lepopup_input_changed(this);&gt;&lt;label for=lepopup-checkbox-55BvwfRLSrYMjmHz-14-0 onclick=lepopup_input_error_hide(this);&gt;&lt;/label&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-cr-label lepopup-ta-left&#34;&gt;&lt;label for=lepopup-checkbox-55BvwfRLSrYMjmHz-14-0 onclick=lepopup_input_error_hide(this);&gt;&lt;/label&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-16 lepopup-element-html&#34; data-type=html data-top=344 data-left=338 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:515;top:344px;left:338px;width:350px;height:5px;&gt;&lt;div class=lepopup-element-html-content&gt;I agree to the &lt;a href=https://www.javacodegeeks.com/about/terms-of-use target=_blank&gt;Terms&lt;/a&gt; and &lt;a href=https://www.javacodegeeks.com/about/privacy-policy target=_blank&gt;Privacy Policy&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-17&#34; data-type=button data-top=372 data-left=308 data-animation-in=bounceIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:516;top:372px;left:308px;width:85px;height:37px;&gt;&lt;a class=&#34;lepopup-button lepopup-button-zoom-out&#34; href=https://www.javacodegeeks.com/feed/ onclick=&#34;return lepopup_submit(this);&#34; data-label=&#34;Sign up&#34; data-loading=Loading...&gt;&lt;span&gt;Sign up&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-19 lepopup-element-html&#34; data-type=html data-top=67 data-left=-15 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:518;top:67px;left:-15px;width:320px;height:363px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2015/01/books_promo.png decoding=async data-src=https://www.javacodegeeks.com/wp-content/uploads/2015/01/books_promo.png alt width=320 height=363&gt;&lt;noscript&gt;&lt;img decoding=async src=https://www.javacodegeeks.com/wp-content/uploads/2015/01/books_promo.png alt width=320 height=363&gt;&lt;/noscript&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-form lepopup-form-60 lepopup-form-kJX2DRnnDmSFHrad lepopup-form-icon-inside lepopup-form-position-middle-right&#34; data-session=0 data-id=kJX2DRnnDmSFHrad data-form-id=60 data-slug=7lQM6oyWL5bTm5lw data-title=&#34;Under the Post Inline&#34; data-page=confirmation data-xd=off data-width=420 data-height=320 data-position=middle-right data-esc=off data-enter=on data-disable-scrollbar=off style=display:none;width:420px;height:320px; onclick=event.stopPropagation();&gt;&lt;div class=lepopup-form-inner style=width:420px;height:320px;&gt;&lt;div class=&#34;lepopup-element lepopup-element-0 lepopup-element-html&#34; data-type=html data-top=80 data-left=70 data-animation-in=bounceInDown data-animation-out=fadeOutUp style=animation-duration:1000ms;animation-delay:0ms;z-index:500;top:80px;left:70px;width:280px;height:160px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;h4 style=&#34;text-align: center; font-size: 18px; font-weight: bold;&#34;&gt;Thank you!&lt;/h4&gt;&lt;p style=&#34;text-align: center;&#34;&gt;We will contact you soon.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;input type=hidden id=lepopup-logic-kJX2DRnnDmSFHrad value=[]&gt;&lt;/div&gt;&lt;div class=&#34;post-bottom-meta post-bottom-tags post-tags-classic&#34;&gt;&lt;div class=post-bottom-meta-title&gt;&lt;span class=tie-icon-tags aria-hidden=true&gt;&lt;/span&gt;Tags&lt;/div&gt;&lt;span class=tagcloud&gt;&lt;a href=https://www.javacodegeeks.com/tag/change-data-capture rel=tag&gt;Change Data Capture&lt;/a&gt; &lt;a href=https://www.javacodegeeks.com/tag/distributed-systems rel=tag&gt;Distributed Systems&lt;/a&gt; &lt;a href=https://www.javacodegeeks.com/tag/event-sourcing rel=tag&gt;Event Sourcing&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div id=post-extra-info&gt;&lt;div class=theiaStickySidebar&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=clearfix&gt;&lt;/div&gt;</description>
      <author>Eleftheria Drosopoulou</author>
      <guid>https://www.javacodegeeks.com/2026/06/event-sourcing-vs-change-data-capture-cdc-choosing-the-right-pattern.html</guid>
      <pubDate>Wed, 24 Jun 2026 06:04:00 +0000</pubDate>
    </item>
    <item>
      <title>Spring HATEOAS + OpenAPI 3.0: Why Links Don’t Appear in Swagger UI</title>
      <link>https://www.javacodegeeks.com/2026/06/spring-hateoas-openapi-3-0-why-links-dont-appear-in-swagger-ui.html</link>
      <description>&lt;header class=entry-header-outer&gt;&lt;nav id=breadcrumb&gt;&lt;a href=https://www.javacodegeeks.com/&gt;&lt;span class=tie-icon-home aria-hidden=true&gt;&lt;/span&gt;Home&lt;/a&gt;&lt;em class=delimiter&gt;»&lt;/em&gt;&lt;a href=https://www.javacodegeeks.com/category/java&gt;Java&lt;/a&gt;&lt;em class=delimiter&gt;»&lt;/em&gt;&lt;a href=https://www.javacodegeeks.com/category/java/enterprise-java&gt;Enterprise Java&lt;/a&gt;&lt;em class=delimiter&gt;»&lt;/em&gt;&lt;span class=current&gt;Spring HATEOAS + OpenAPI 3.0: Why Links Don’t Appear in Swagger UI&lt;/span&gt;&lt;/nav&gt;&lt;div class=entry-header&gt;&lt;span class=post-cat-wrap&gt;&lt;a class=&#34;post-cat tie-cat-8&#34; href=https://www.javacodegeeks.com/category/java/enterprise-java&gt;Enterprise Java&lt;/a&gt;&lt;/span&gt;&lt;h1 class=&#34;post-title entry-title&#34;&gt;Spring HATEOAS + OpenAPI 3.0: Why Links Don’t Appear in Swagger UI&lt;/h1&gt;&lt;/div&gt;&lt;/header&gt;&lt;div class=&#34;entry-content entry clearfix&#34;&gt;&lt;div class=&#34;stream-item stream-item-above-post-content&#34;&gt;&lt;div class=stream-item-size&gt;&lt;div id=adngin-in-post-0 style=&#34;float:left; margin-right:20px; margin-bottom:10px; width:300px; height:274px;&#34;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;em&gt;You built a perfectly valid HAL response, opened Swagger, and the &lt;code&gt;_links&lt;/code&gt; are simply… gone. Here is exactly why that happens and how to fix it for good.&lt;/em&gt;&lt;p&gt;If you have spent any time combining &lt;a href=https://spring.io/projects/spring-hateoas target=_blank rel=&#34;noreferrer noopener&#34;&gt;Spring HATEOAS&lt;/a&gt; with &lt;a href=https://springdoc.org/ target=_blank rel=&#34;noreferrer noopener&#34;&gt;springdoc-openapi&lt;/a&gt;, you have almost certainly hit the wall: your REST endpoint returns a beautifully structured HAL payload at runtime, but Swagger UI shows something completely different — or worse, it shows the raw internals of &lt;code&gt;EntityModel&lt;/code&gt; instead of your clean &lt;code&gt;_links&lt;/code&gt; map. As a result, your API consumers get misleading documentation. So, let’s dig into why this happens and, more importantly, how to get past it.&lt;h2 class=wp-block-heading&gt;The Problem in Plain Language&lt;/h2&gt;&lt;p&gt;Before we jump into solutions, it is worth understanding what is actually going on under the hood. Spring HATEOAS serializes responses using custom Jackson modules that transform &lt;code&gt;EntityModel&amp;lt;T&amp;gt;&lt;/code&gt; and &lt;code&gt;CollectionModel&amp;lt;T&amp;gt;&lt;/code&gt; into the well-known &lt;a href=https://stateless.group/hal_specification.html target=_blank rel=&#34;noreferrer noopener&#34;&gt;HAL (Hypertext Application Language)&lt;/a&gt; format at runtime. The resulting JSON looks something like this:&lt;pre class=brush:js&gt;{&#xA;  &amp;#34;id&amp;#34;: 42,&#xA;  &amp;#34;name&amp;#34;: &amp;#34;Laptop&amp;#34;,&#xA;  &amp;#34;_links&amp;#34;: {&#xA;    &amp;#34;self&amp;#34;: { &amp;#34;href&amp;#34;: &amp;#34;/api/products/42&amp;#34; },&#xA;    &amp;#34;category&amp;#34;: { &amp;#34;href&amp;#34;: &amp;#34;/api/categories/electronics&amp;#34; }&#xA;  }&#xA;}&#xA;&lt;/pre&gt;&lt;p&gt;That looks great in Postman or a browser. However, the springdoc schema generator runs at application startup — &lt;em&gt;before&lt;/em&gt; any request is made — and it inspects the raw Java class structure. Since it does not invoke the Jackson serializers at that point, it sees &lt;code&gt;EntityModel&lt;/code&gt;‘s internal field named &lt;code&gt;links&lt;/code&gt; (a plain Java collection) rather than the HAL-mapped &lt;code&gt;_links&lt;/code&gt; object. The gap between what the serializer produces and what the schema generator sees is the root cause of everything that follows.&lt;blockquote class=&#34;wp-block-quote is-layout-flow wp-block-quote-is-layout-flow&#34;&gt;&lt;p&gt;springdoc reads class structure at startup. Spring HATEOAS serializes data at request time. These two worlds never directly talk to each other unless you wire them up.&lt;/blockquote&gt;&lt;h2 class=wp-block-heading&gt;The Three Most Common Symptoms&lt;/h2&gt;&lt;p&gt;Depending on how your project is set up, the broken documentation typically shows up in one of three ways. Recognizing which one you are dealing with saves a lot of debugging time.&lt;figure class=wp-block-table&gt;&lt;table class=has-fixed-layout&gt;&lt;thead&gt;&lt;tr&gt;&lt;th class=has-text-align-left data-align=left&gt;What Swagger Shows&lt;th class=has-text-align-left data-align=left&gt;What It Actually Means&lt;th class=has-text-align-left data-align=left&gt;Severity&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;links&lt;/code&gt; as an array of full &lt;code&gt;Link&lt;/code&gt; objects&lt;td&gt;springdoc is reading the raw Java class, not HAL serialization&lt;td&gt;Misleading&lt;tr&gt;&lt;td&gt;&lt;code&gt;_links&lt;/code&gt; shown as array instead of object/map&lt;td&gt;Schema type mismatch — HAL expects an object keyed by rel name&lt;td&gt;Wrong schema&lt;tr&gt;&lt;td&gt;No &lt;code&gt;_links&lt;/code&gt; field at all&lt;td&gt;Missing HATEOAS module dependency or incorrect return type hint&lt;td&gt;Invisible&lt;/table&gt;&lt;/figure&gt;&lt;p&gt;Additionally, you might also encounter &lt;code&gt;_embedded&lt;/code&gt; showing up as &lt;code&gt;content&lt;/code&gt; on &lt;code&gt;CollectionModel&lt;/code&gt; responses, which breaks HAL consumers who rely on the underscore-prefixed convention. All of these issues share the same underlying cause, so fortunately they also share similar fixes.&lt;h2 class=wp-block-heading&gt;Fix 1: Add the Correct Dependency&lt;/h2&gt;&lt;p&gt;This one sounds obvious, but it catches a surprising number of teams. The standard &lt;code&gt;springdoc-openapi-starter-webmvc-ui&lt;/code&gt; does not automatically activate HATEOAS-aware schema generation. You need to ensure you are also pulling in &lt;code&gt;spring-boot-starter-hateoas&lt;/code&gt;, and more specifically that you are using the right springdoc starter for your context.&lt;p&gt;For a &lt;strong&gt;Spring Boot 3.x&lt;/strong&gt; project using Spring MVC, your &lt;code&gt;pom.xml&lt;/code&gt; should look like this:&lt;pre class=brush:xml&gt;&amp;lt;dependency&amp;gt;&#xA;  &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;&#xA;  &amp;lt;artifactId&amp;gt;spring-boot-starter-hateoas&amp;lt;/artifactId&amp;gt;&#xA;&amp;lt;/dependency&amp;gt;&#xA;&#xA;&amp;lt;dependency&amp;gt;&#xA;  &amp;lt;groupId&amp;gt;org.springdoc&amp;lt;/groupId&amp;gt;&#xA;  &amp;lt;artifactId&amp;gt;springdoc-openapi-starter-webmvc-ui&amp;lt;/artifactId&amp;gt;&#xA;  &amp;lt;version&amp;gt;2.8.4&amp;lt;/version&amp;gt;&#xA;&amp;lt;/dependency&amp;gt;&#xA;&lt;/pre&gt;&lt;p&gt;When &lt;code&gt;spring-boot-starter-hateoas&lt;/code&gt; is on the classpath, springdoc’s autoconfiguration detects it and activates &lt;code&gt;OpenApiHateoasLinksCustomizer&lt;/code&gt; automatically — provided you are on springdoc 2.x. On version 1.x, you also needed a separate &lt;code&gt;springdoc-openapi-hateoas&lt;/code&gt; artifact; that separate module was folded into the core starter in v2.&lt;blockquote class=&#34;wp-block-quote is-layout-flow wp-block-quote-is-layout-flow&#34;&gt;&lt;p&gt;If you are still on Spring Boot 2 and springdoc 1.x, you explicitly need to add &lt;code&gt;springdoc-openapi-hateoas&lt;/code&gt; as a separate dependency. Without it, HATEOAS schema support simply does not activate.&lt;div style=&#34;display:inline-block; margin: 15px 0;&#34;&gt;&lt;div id=adngin-JavaCodeGeeks_incontent_video-0 style=display:inline-block;&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;/blockquote&gt;&lt;h2 class=wp-block-heading&gt;Fix 2: Return the Right Types from Your Controller&lt;/h2&gt;&lt;p&gt;springdoc infers the schema entirely from the method return type. Consequently, if your controller returns &lt;code&gt;ResponseEntity&amp;lt;?&amp;gt;&lt;/code&gt; with a wildcard, or if you are returning a raw domain object that you happen to wrap inside a &lt;code&gt;EntityModel&lt;/code&gt; later, springdoc misses the HATEOAS wrapper entirely.&lt;p&gt;The fix is straightforward — always be explicit with your generics:&lt;pre class=brush:java&gt;// Avoid — springdoc cannot infer the schema&#xA;@GetMapping(&amp;#34;/products/{id}&amp;#34;)&#xA;public ResponseEntity getProduct(@PathVariable Long id) {&#xA;    Product product = service.findById(id);&#xA;    return ResponseEntity.ok(EntityModel.of(product));&#xA;}&#xA;&#xA;// Preferred — explicit type lets springdoc map the schema correctly&#xA;@GetMapping(&amp;#34;/products/{id}&amp;#34;)&#xA;public EntityModel&amp;lt;Product&amp;gt; getProduct(@PathVariable Long id) {&#xA;    Product product = service.findById(id);&#xA;    return EntityModel.of(product,&#xA;        linkTo(methodOn(ProductController.class).getProduct(id)).withSelfRel(),&#xA;        linkTo(methodOn(CategoryController.class).getCategory(product.getCategoryId())).withRel(&amp;#34;category&amp;#34;)&#xA;    );&#xA;}&#xA;&lt;/pre&gt;&lt;p&gt;Equally important: for collections, return &lt;code&gt;CollectionModel&amp;lt;EntityModel&amp;lt;Product&amp;gt;&amp;gt;&lt;/code&gt; rather than &lt;code&gt;List&amp;lt;EntityModel&amp;lt;Product&amp;gt;&amp;gt;&lt;/code&gt;. springdoc knows how to unwrap the nested generics and generate the correct &lt;code&gt;_embedded&lt;/code&gt; structure when you are specific.&lt;h3 class=wp-block-heading&gt;Annotating with @Operation and @ApiResponse&lt;/h3&gt;&lt;p&gt;Sometimes the return type alone is not enough — especially when you use &lt;code&gt;ResponseEntity&lt;/code&gt; for HTTP status control. In those cases, complement your method signature with a Swagger annotation to spell out exactly what the response looks like:&lt;pre class=brush:java&gt;@Operation(summary = &amp;#34;Get a product by ID&amp;#34;)&#xA;@ApiResponse(responseCode = &amp;#34;200&amp;#34;,&#xA;    content = @Content(schema = @Schema(implementation = ProductEntityModel.class)))&#xA;@GetMapping(&amp;#34;/products/{id}&amp;#34;)&#xA;public ResponseEntity&amp;lt;EntityModel&amp;lt;Product&amp;gt;&amp;gt; getProduct(@PathVariable Long id) {&#xA;    // ...&#xA;}&#xA;&lt;/pre&gt;&lt;p&gt;This combination gives springdoc an unambiguous signal about the schema, so the generated documentation reliably reflects your actual HAL output.&lt;h2 class=wp-block-heading&gt;Fix 3: Understand the _links vs links Naming Gap&lt;/h2&gt;&lt;p&gt;Even after the above fixes, you may notice that Swagger still shows the field as &lt;code&gt;links&lt;/code&gt; (no underscore) rather than &lt;code&gt;_links&lt;/code&gt;. This is because, as &lt;a href=https://github.com/springdoc/springdoc-openapi/issues/401 target=_blank rel=&#34;noreferrer noopener&#34;&gt;reported in the springdoc issue tracker&lt;/a&gt;, the schema generator reads the Java field name rather than the HAL-serialized name.&lt;p&gt;springdoc 2.x with HATEOAS autoconfiguration should handle this automatically via its built-in &lt;code&gt;OpenApiHateoasLinksCustomizer&lt;/code&gt;. However, if you still see plain &lt;code&gt;links&lt;/code&gt; in the schema, you can register a customizer bean yourself to fix the field name:&lt;pre class=brush:java&gt;@Configuration&#xA;public class OpenApiConfig {&#xA;&#xA;    @Bean&#xA;    public OpenApiCustomizer hateoasLinksCustomizer() {&#xA;        return openApi -&amp;gt; openApi.getComponents()&#xA;            .getSchemas()&#xA;            .forEach((name, schema) -&amp;gt; {&#xA;                if (schema.getProperties() != null&#xA;                        &amp;amp;&amp;amp; schema.getProperties().containsKey(&amp;#34;links&amp;#34;)) {&#xA;                    var linksSchema = schema.getProperties().remove(&amp;#34;links&amp;#34;);&#xA;                    schema.getProperties().put(&amp;#34;_links&amp;#34;, linksSchema);&#xA;                }&#xA;            });&#xA;    }&#xA;}&#xA;&lt;/pre&gt;&lt;p&gt;This walks the generated component schemas and renames the &lt;code&gt;links&lt;/code&gt; property to &lt;code&gt;_links&lt;/code&gt; everywhere it appears. As a result, your Swagger UI will finally mirror the actual HAL payload your API produces.&lt;blockquote class=&#34;wp-block-quote is-layout-flow wp-block-quote-is-layout-flow&#34;&gt;&lt;p&gt;&lt;strong&gt;After the fix&lt;/strong&gt; your Swagger schema should show &lt;code&gt;_links&lt;/code&gt; as an object with string keys mapping to link objects — matching what HAL actually delivers at runtime.&lt;/blockquote&gt;&lt;h2 class=wp-block-heading&gt;How the Schema Should Look After Fixing&lt;/h2&gt;&lt;p&gt;With all the above pieces in place, the OpenAPI schema for a &lt;code&gt;EntityModel&amp;lt;Product&amp;gt;&lt;/code&gt; response should end up looking like this in the generated &lt;code&gt;v3/api-docs&lt;/code&gt; output:&lt;pre class=brush:js&gt;{&#xA;  &amp;#34;EntityModelProduct&amp;#34;: {&#xA;    &amp;#34;type&amp;#34;: &amp;#34;object&amp;#34;,&#xA;    &amp;#34;properties&amp;#34;: {&#xA;      &amp;#34;id&amp;#34;: { &amp;#34;type&amp;#34;: &amp;#34;integer&amp;#34;, &amp;#34;format&amp;#34;: &amp;#34;int64&amp;#34; },&#xA;      &amp;#34;name&amp;#34;: { &amp;#34;type&amp;#34;: &amp;#34;string&amp;#34; },&#xA;      &amp;#34;_links&amp;#34;: {&#xA;        &amp;#34;type&amp;#34;: &amp;#34;object&amp;#34;,&#xA;        &amp;#34;additionalProperties&amp;#34;: {&#xA;          &amp;#34;$ref&amp;#34;: &amp;#34;#/components/schemas/Link&amp;#34;&#xA;        }&#xA;      }&#xA;    }&#xA;  },&#xA;  &amp;#34;Link&amp;#34;: {&#xA;    &amp;#34;type&amp;#34;: &amp;#34;object&amp;#34;,&#xA;    &amp;#34;properties&amp;#34;: {&#xA;      &amp;#34;href&amp;#34;:      { &amp;#34;type&amp;#34;: &amp;#34;string&amp;#34; },&#xA;      &amp;#34;templated&amp;#34;: { &amp;#34;type&amp;#34;: &amp;#34;boolean&amp;#34; }&#xA;    }&#xA;  }&#xA;}&#xA;&lt;/pre&gt;&lt;p&gt;Notice that &lt;code&gt;_links&lt;/code&gt; is an object with &lt;code&gt;additionalProperties&lt;/code&gt; referencing &lt;code&gt;Link&lt;/code&gt; — not a flat array. That is the correct HAL representation and the one that will render properly in Swagger UI.&lt;h2 class=wp-block-heading&gt;The Serialization Gap at a Glance&lt;/h2&gt;&lt;p&gt;The chart below visualizes how the divergence between springdoc’s schema generation and Spring HATEOAS runtime serialization leads to documentation drift, and at which layer each fix operates.&lt;p class=has-text-align-center&gt;&lt;strong&gt;Where Documentation Drift Happens&lt;/strong&gt;&lt;div class=wp-block-image&gt;&lt;figure class=&#34;aligncenter size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-19_20-58-20.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-19_20-58-20.png fetchpriority=high decoding=async width=506 height=276 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-19_20-58-20.png alt class=wp-image-144084 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-19_20-58-20.png 506w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-19_20-58-20-300x164.png 300w&#34; data-sizes=&#34;(max-width: 506px) 100vw, 506px&#34;&gt;&lt;noscript&gt;&lt;img fetchpriority=high decoding=async width=506 height=276 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-19_20-58-20.png alt class=wp-image-144084 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-19_20-58-20.png 506w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-19_20-58-20-300x164.png 300w&#34; sizes=&#34;(max-width: 506px) 100vw, 506px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;figcaption class=wp-element-caption&gt;Comparison of what each layer produces vs. what Swagger receives — before and after fixes&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&lt;h2 class=wp-block-heading&gt;Common Edge Cases to Watch Out For&lt;/h2&gt;&lt;h3 class=wp-block-heading&gt;PagedModel and pagination links&lt;/h3&gt;&lt;p&gt;If you use &lt;code&gt;PagedModel&amp;lt;EntityModel&amp;lt;T&amp;gt;&amp;gt;&lt;/code&gt;, springdoc should also show the pagination links (&lt;code&gt;first&lt;/code&gt;, &lt;code&gt;prev&lt;/code&gt;, &lt;code&gt;next&lt;/code&gt;, &lt;code&gt;last&lt;/code&gt;) in the schema. However, this only works when spring-boot-starter-hateoas is properly detected. If you do not see them, double-check that your return type uses &lt;code&gt;PagedModel&lt;/code&gt; explicitly rather than Spring Data’s &lt;code&gt;Page&lt;/code&gt;.&lt;h3 class=wp-block-heading&gt;Custom RepresentationModel subclasses&lt;/h3&gt;&lt;p&gt;When you extend &lt;code&gt;RepresentationModel&amp;lt;T&amp;gt;&lt;/code&gt; directly to create a custom representation, springdoc may generate the &lt;code&gt;_links&lt;/code&gt; field as an array instead of a map — especially on subtypes using &lt;code&gt;@Schema(allOf = ...)&lt;/code&gt;. This is a &lt;a href=https://github.com/springdoc/springdoc-openapi/issues/3161 target=_blank rel=&#34;noreferrer noopener&#34;&gt;known issue tracked in the springdoc repository&lt;/a&gt;. The workaround is to annotate the &lt;code&gt;_links&lt;/code&gt; property explicitly with &lt;code&gt;@Schema&lt;/code&gt; to override the generated type:&lt;pre class=brush:java&gt;public class ProductModel extends RepresentationModel&amp;lt;ProductModel&amp;gt; {&#xA;&#xA;    private String name;&#xA;    private String sku;&#xA;&#xA;    @Schema(description = &amp;#34;HAL links map&amp;#34;,&#xA;            additionalPropertiesSchema = @Schema(ref = &amp;#34;#/components/schemas/Link&amp;#34;))&#xA;    @JsonProperty(&amp;#34;_links&amp;#34;)&#xA;    public Links getLinks() {&#xA;        return super.getLinks();&#xA;    }&#xA;}&#xA;&lt;/pre&gt;&lt;h3 class=wp-block-heading&gt;HalConfiguration and single-link arrays&lt;/h3&gt;&lt;p&gt;If you have configured &lt;code&gt;HalConfiguration&lt;/code&gt; to render single links as arrays rather than objects, your runtime payload changes shape — and the default springdoc schema will be wrong again. In that case, you need a custom &lt;code&gt;OpenApiCustomizer&lt;/code&gt; that also adjusts the &lt;code&gt;_links&lt;/code&gt; additionalProperties to accept an array of &lt;code&gt;Link&lt;/code&gt;.&lt;h2 class=wp-block-heading&gt;Dependency Compatibility at a Glance&lt;/h2&gt;&lt;p&gt;Getting the right dependency versions together is half the battle. The following table summarizes the tested combinations that produce correct HATEOAS documentation:&lt;figure class=wp-block-table&gt;&lt;table class=has-fixed-layout&gt;&lt;thead&gt;&lt;tr&gt;&lt;th class=has-text-align-left data-align=left&gt;Spring Boot&lt;th class=has-text-align-left data-align=left&gt;springdoc-openapi&lt;th class=has-text-align-left data-align=left&gt;HATEOAS module needed?&lt;th class=has-text-align-left data-align=left&gt;Status&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;3.2.x – 3.5.x&lt;td&gt;2.3.x – 2.8.x&lt;td&gt;No separate module — built in&lt;td&gt;Fully supported&lt;tr&gt;&lt;td&gt;2.7.x&lt;td&gt;1.6.x – 1.8.x&lt;td&gt;Yes — &lt;code&gt;springdoc-openapi-hateoas&lt;/code&gt;&lt;td&gt;Supported (EOL)&lt;tr&gt;&lt;td&gt;3.x with springfox&lt;td&gt;n/a (springfox)&lt;td&gt;springfox does not support HATEOAS well&lt;td&gt;Avoid&lt;tr&gt;&lt;td&gt;Any&lt;td&gt;Any&lt;td&gt;Missing &lt;code&gt;spring-boot-starter-hateoas&lt;/code&gt;&lt;td&gt;Links invisible&lt;/table&gt;&lt;/figure&gt;&lt;h2 class=wp-block-heading&gt;A Realistic Adoption Timeline&lt;/h2&gt;&lt;p&gt;To give you a sense of how teams typically progress from broken to fully fixed documentation, the chart below shows an approximate timeline of issue discovery and resolution effort based on real reports in the springdoc and Spring HATEOAS repositories.&lt;p class=has-text-align-center&gt;&lt;strong&gt;Developer Hours to Full Resolution — Typical Progression&lt;/strong&gt;&lt;div class=wp-block-image&gt;&lt;figure class=&#34;aligncenter size-full&#34;&gt;&lt;a href=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-19_21-00-07.png&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-19_21-00-07.png decoding=async width=504 height=256 data-src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-19_21-00-07.png alt class=wp-image-144085 data-srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-19_21-00-07.png 504w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-19_21-00-07-300x152.png 300w&#34; data-sizes=&#34;(max-width: 504px) 100vw, 504px&#34;&gt;&lt;noscript&gt;&lt;img decoding=async width=504 height=256 src=https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-19_21-00-07.png alt class=wp-image-144085 srcset=&#34;https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-19_21-00-07.png 504w, https://www.javacodegeeks.com/wp-content/uploads/2026/06/2026-06-19_21-00-07-300x152.png 300w&#34; sizes=&#34;(max-width: 504px) 100vw, 504px&#34;&gt;&lt;/noscript&gt;&lt;/a&gt;&lt;figcaption class=wp-element-caption&gt;Averaged across reported GitHub issues and community posts. Each bar represents cumulative effort at that stage.&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&lt;h2 class=wp-block-heading&gt;Quick Diagnostic Checklist&lt;/h2&gt;&lt;p&gt;Before you reach for a custom &lt;code&gt;OpenApiCustomizer&lt;/code&gt;, it is worth running through this quick list to rule out the simpler causes first. In most cases, one of the first three items is all you need.&lt;ul class=wp-block-list&gt;&lt;li&gt;Is &lt;code&gt;spring-boot-starter-hateoas&lt;/code&gt; in your &lt;code&gt;pom.xml&lt;/code&gt; or &lt;code&gt;build.gradle&lt;/code&gt;?&lt;li&gt;Are you on springdoc 2.x (not springfox) with Spring Boot 3.x?&lt;li&gt;Does your controller return an explicit generic type like &lt;code&gt;EntityModel&amp;lt;Product&amp;gt;&lt;/code&gt; rather than &lt;code&gt;ResponseEntity&amp;lt;?&amp;gt;&lt;/code&gt;?&lt;li&gt;Have you checked &lt;code&gt;/v3/api-docs&lt;/code&gt; directly (not just Swagger UI) to see the raw generated schema?&lt;li&gt;If using &lt;code&gt;@Schema(subTypes)&lt;/code&gt;, are your subtypes annotated correctly without shadowing &lt;code&gt;_links&lt;/code&gt;?&lt;/ul&gt;&lt;blockquote class=&#34;wp-block-quote is-layout-flow wp-block-quote-is-layout-flow&#34;&gt;&lt;p&gt;The &lt;a href=https://springdoc.org/ target=_blank rel=&#34;noreferrer noopener&#34;&gt;official springdoc documentation&lt;/a&gt; covers the HATEOAS integration in detail. The &lt;a href=https://docs.spring.io/spring-hateoas/docs/current/reference/html/ target=_blank rel=&#34;noreferrer noopener&#34;&gt;Spring HATEOAS reference guide&lt;/a&gt; explains how serializers and link discoverers work under the hood — both are worth a read if you are building a production-grade hypermedia API.&lt;/blockquote&gt;&lt;h2 class=wp-block-heading&gt;What We Learned&lt;/h2&gt;&lt;p&gt;The root of the Spring HATEOAS + Swagger problem is a timing mismatch: springdoc reads your class structure at startup, while Spring HATEOAS transforms it with custom Jackson serializers at request time. As a result, the two worlds produce different schemas unless you explicitly bridge them.&lt;p&gt;Throughout this article, we walked through the three most common symptoms — wrong field names, array vs. object mismatches, and invisible links.&lt;p&gt;We then covered the exact fixes: adding &lt;code&gt;spring-boot-starter-hateoas&lt;/code&gt;, using explicit generic return types in controllers, registering an &lt;code&gt;OpenApiCustomizer&lt;/code&gt; to correct field names, and handling edge cases like &lt;code&gt;PagedModel&lt;/code&gt; and custom &lt;code&gt;RepresentationModel&lt;/code&gt; subclasses. With all these pieces in place, your Swagger UI documentation will accurately reflect what your HAL responses deliver at runtime — which is the whole point.&lt;/p&gt;&lt;style&gt;.lepopup-progress-60 div.lepopup-progress-t1&gt;div{background-color:#e0e0e0;}.lepopup-progress-60 div.lepopup-progress-t1&gt;div&gt;div{background-color:#bd4070;}.lepopup-progress-60 div.lepopup-progress-t1&gt;div&gt;div{color:#ffffff;}.lepopup-progress-60 div.lepopup-progress-t1&gt;label{color:#444444;}.lepopup-form-60, .lepopup-form-60 *, .lepopup-progress-60 {font-size:15px;color:#444444;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-signature-box span i{font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#555555;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-signature-box,.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;text&#39;],.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;email&#39;],.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;password&#39;],.lepopup-form-60 .lepopup-element div.lepopup-input select,.lepopup-form-60 .lepopup-element div.lepopup-input select option,.lepopup-form-60 .lepopup-element div.lepopup-input textarea{font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#555555;font-style:normal;text-decoration:none;text-align:left;background-color:rgba(255, 255, 255, 0.7);background-image:none;border-width:1px;border-style:solid;border-color:#cccccc;border-radius:0px;box-shadow: inset 0px 0px 15px -7px #000000;}.lepopup-form-60 .lepopup-element div.lepopup-input ::placeholder{color:#555555; opacity: 0.9;} .lepopup-form-60 .lepopup-element div.lepopup-input ::-ms-input-placeholder{color:#555555; opacity: 0.9;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect::-webkit-scrollbar-thumb{background-color:#cccccc;}.lepopup-form-60 .lepopup-element div.lepopup-input&gt;i.lepopup-icon-left, .lepopup-form-60 .lepopup-element div.lepopup-input&gt;i.lepopup-icon-right{font-size:20px;color:#444444;border-radius:0px;}.lepopup-form-60 .lepopup-element .lepopup-button,.lepopup-form-60 .lepopup-element .lepopup-button:visited{font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#ffffff;font-weight:700;font-style:normal;text-decoration:none;text-align:center;background-color:#326693;background-image:none;border-width:1px;border-style:solid;border-color:#326693;border-radius:0px;box-shadow:none;}.lepopup-form-60 .lepopup-element div.lepopup-input .lepopup-imageselect+label{border-width:1px;border-style:solid;border-color:#cccccc;border-radius:0px;box-shadow:none;}.lepopup-form-60 .lepopup-element div.lepopup-input .lepopup-imageselect+label span.lepopup-imageselect-label{font-size:15px;color:#444444;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl:checked+label:after{background-color:rgba(255, 255, 255, 0.7);}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-classic+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-fa-check+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-square+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl+label{background-color:rgba(255, 255, 255, 0.7);border-color:#cccccc;color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-square:checked+label:after{background-color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl:checked+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl+label:after{background-color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-classic+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-fa-check+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-dot+label{background-color:rgba(255, 255, 255, 0.7);border-color:#cccccc;color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-dot:checked+label:after{background-color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect&gt;input[type=&#39;checkbox&#39;]+label:hover{background-color:#bd4070;color:#ffffff;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect&gt;input[type=&#39;checkbox&#39;]:checked+label{background-color:#a93a65;color:#ffffff;}.lepopup-form-60 .lepopup-element input[type=&#39;checkbox&#39;].lepopup-tile+label, .lepopup-form-60 .lepopup-element input[type=&#39;radio&#39;].lepopup-tile+label {font-size:15px;color:#444444;font-style:normal;text-decoration:none;text-align:center;background-color:#ffffff;background-image:none;border-width:1px;border-style:solid;border-color:#cccccc;border-radius:0px;box-shadow:none;}.lepopup-form-60 .lepopup-element-error{font-size:15px;color:#ffffff;font-style:normal;text-decoration:none;text-align:left;background-color:#d9534f;background-image:none;}.lepopup-form-60 .lepopup-element-2 {background-color:rgba(226, 236, 250, 1);background-image:none;border-width:1px;border-style:solid;border-color:rgba(216, 216, 216, 1);border-radius:3px;box-shadow: 1px 1px 15px -6px #d7e1eb;}.lepopup-form-60 .lepopup-element-3 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:26px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-3 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:26px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-3 .lepopup-element-html-content {min-height:73px;}.lepopup-form-60 .lepopup-element-4 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:19px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-4 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:19px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-4 .lepopup-element-html-content {min-height:23px;}.lepopup-form-60 .lepopup-element-5 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-5 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-5 .lepopup-element-html-content {min-height:24px;}.lepopup-form-60 .lepopup-element-6 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-6 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-6 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-7 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-7 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-7 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-8 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-8 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-8 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-9 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-9 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-9 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-10 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-10 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-10 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-11 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-11 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-11 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-12 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-12 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-12 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-13 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-13 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-13 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-14 div.lepopup-input .lepopup-icon-left, .lepopup-form-60 .lepopup-element-14 div.lepopup-input .lepopup-icon-right {line-height:36px;}.lepopup-form-60 .lepopup-element-15 div.lepopup-input{height:auto;line-height:1;}.lepopup-form-60 .lepopup-element-16 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:14px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-16 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:14px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-16 .lepopup-element-html-content {min-height:5px;}.lepopup-form-60 .lepopup-element-19 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#333333;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-19 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#333333;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-19 .lepopup-element-html-content {min-height:363px;}.lepopup-form-60 .lepopup-element-0 * {font-size:15px;color:#ffffff;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-0 {font-size:15px;color:#ffffff;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:#5cb85c;background-image:none;border-width:0px;border-style:solid;border-color:#ccc;border-radius:5px;box-shadow: 1px 1px 15px -6px #000000;padding-top:40px;padding-right:40px;padding-bottom:40px;padding-left:40px;}.lepopup-form-60 .lepopup-element-0 .lepopup-element-html-content {min-height:160px;}&lt;/style&gt;&lt;div class=lepopup-inline style=&#34;margin: 0 auto;&#34;&gt;&lt;div class=&#34;lepopup-form lepopup-form-60 lepopup-form-3oplLWOHvQuyWxe4 lepopup-form-icon-inside lepopup-form-position-middle-right&#34; data-session=0 data-id=3oplLWOHvQuyWxe4 data-form-id=60 data-slug=7lQM6oyWL5bTm5lw data-title=&#34;Under the Post Inline&#34; data-page=1 data-xd=off data-width=820 data-height=430 data-position=middle-right data-esc=off data-enter=on data-disable-scrollbar=off style=display:none;width:820px;height:430px; onclick=event.stopPropagation();&gt;&lt;div class=lepopup-form-inner style=width:820px;height:430px;&gt;&lt;div class=&#34;lepopup-element lepopup-element-2 lepopup-element-rectangle&#34; data-type=rectangle data-top=0 data-left=0 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:501;top:0px;left:0px;width:820px;height:430px;&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-3 lepopup-element-html&#34; data-type=html data-top=7 data-left=10 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:502;top:7px;left:10px;width:797px;height:73px;&gt;&lt;div class=lepopup-element-html-content&gt;Do you want to know how to develop your skillset to become a &lt;span style=&#34;color: #CAB43D; text-shadow: 1px 1px #835D5D;&#34;&gt;Java Rockstar?&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-4 lepopup-element-html&#34; data-type=html data-top=83 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:503;top:83px;left:308px;width:473px;height:23px;&gt;&lt;div class=lepopup-element-html-content&gt;Subscribe to our newsletter to start Rocking &lt;span style=&#34;text-decoration: underline;&#34;&gt;right now!&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-5 lepopup-element-html&#34; data-type=html data-top=107 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:504;top:107px;left:308px;width:473px;height:24px;&gt;&lt;div class=lepopup-element-html-content&gt;To get you started we give you our best selling eBooks for &lt;span style=&#34;color:#e01404; text-shadow: 1px 1px #C99924; font-size: 15px;&#34;&gt;FREE!&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-6 lepopup-element-html&#34; data-type=html data-top=136 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:505;top:136px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;1.&lt;/span&gt; JPA Mini Book&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-7 lepopup-element-html&#34; data-type=html data-top=156 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:506;top:156px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;2.&lt;/span&gt; JVM Troubleshooting Guide&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-8 lepopup-element-html&#34; data-type=html data-top=176 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:507;top:176px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;3.&lt;/span&gt; JUnit Tutorial for Unit Testing&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-9 lepopup-element-html&#34; data-type=html data-top=196 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:508;top:196px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;4.&lt;/span&gt; Java Annotations Tutorial&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-10 lepopup-element-html&#34; data-type=html data-top=216 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:509;top:216px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;5.&lt;/span&gt; Java Interview Questions&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-11 lepopup-element-html&#34; data-type=html data-top=236 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:510;top:236px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;6.&lt;/span&gt; Spring Interview Questions&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-12 lepopup-element-html&#34; data-type=html data-top=256 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:511;top:256px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;7.&lt;/span&gt; Android UI Design&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-13 lepopup-element-html&#34; data-type=html data-top=282 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:512;top:282px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;and many more ....&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-14&#34; data-type=email data-deps data-id=14 data-top=305 data-left=308 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:513;top:305px;left:308px;width:473px;height:36px;&gt;&lt;div class=lepopup-input&gt;&lt;input type=email name=lepopup-14 class=lepopup-ta-left placeholder=&#34;Enter your e-mail...&#34; autocomplete=email data-default aria-label=&#34;Email Field&#34; oninput=lepopup_input_changed(this); onfocus=lepopup_input_error_hide(this);&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-15&#34; data-type=checkbox data-deps data-id=15 data-top=344 data-left=308 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:514;top:344px;left:308px;width:160px;&gt;&lt;div class=&#34;lepopup-input lepopup-cr-layout-1 lepopup-cr-layout-left&#34;&gt;&lt;div class=&#34;lepopup-cr-container lepopup-cr-container-medium lepopup-cr-container-left&#34;&gt;&lt;div class=lepopup-cr-box&gt;&lt;input class=&#34;lepopup-checkbox lepopup-checkbox-classic lepopup-checkbox-medium&#34; type=checkbox name=lepopup-15[] id=lepopup-checkbox-yAMBvnR3KoiMmHoe-14-0 value=on data-default=off onchange=lepopup_input_changed(this);&gt;&lt;label for=lepopup-checkbox-yAMBvnR3KoiMmHoe-14-0 onclick=lepopup_input_error_hide(this);&gt;&lt;/label&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-cr-label lepopup-ta-left&#34;&gt;&lt;label for=lepopup-checkbox-yAMBvnR3KoiMmHoe-14-0 onclick=lepopup_input_error_hide(this);&gt;&lt;/label&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-16 lepopup-element-html&#34; data-type=html data-top=344 data-left=338 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:515;top:344px;left:338px;width:350px;height:5px;&gt;&lt;div class=lepopup-element-html-content&gt;I agree to the &lt;a href=https://www.javacodegeeks.com/about/terms-of-use target=_blank&gt;Terms&lt;/a&gt; and &lt;a href=https://www.javacodegeeks.com/about/privacy-policy target=_blank&gt;Privacy Policy&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-17&#34; data-type=button data-top=372 data-left=308 data-animation-in=bounceIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:516;top:372px;left:308px;width:85px;height:37px;&gt;&lt;a class=&#34;lepopup-button lepopup-button-zoom-out&#34; href=https://www.javacodegeeks.com/feed/ onclick=&#34;return lepopup_submit(this);&#34; data-label=&#34;Sign up&#34; data-loading=Loading...&gt;&lt;span&gt;Sign up&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-19 lepopup-element-html&#34; data-type=html data-top=67 data-left=-15 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:518;top:67px;left:-15px;width:320px;height:363px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2015/01/books_promo.png decoding=async data-src=https://www.javacodegeeks.com/wp-content/uploads/2015/01/books_promo.png alt width=320 height=363&gt;&lt;noscript&gt;&lt;img decoding=async src=https://www.javacodegeeks.com/wp-content/uploads/2015/01/books_promo.png alt width=320 height=363&gt;&lt;/noscript&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-form lepopup-form-60 lepopup-form-3oplLWOHvQuyWxe4 lepopup-form-icon-inside lepopup-form-position-middle-right&#34; data-session=0 data-id=3oplLWOHvQuyWxe4 data-form-id=60 data-slug=7lQM6oyWL5bTm5lw data-title=&#34;Under the Post Inline&#34; data-page=confirmation data-xd=off data-width=420 data-height=320 data-position=middle-right data-esc=off data-enter=on data-disable-scrollbar=off style=display:none;width:420px;height:320px; onclick=event.stopPropagation();&gt;&lt;div class=lepopup-form-inner style=width:420px;height:320px;&gt;&lt;div class=&#34;lepopup-element lepopup-element-0 lepopup-element-html&#34; data-type=html data-top=80 data-left=70 data-animation-in=bounceInDown data-animation-out=fadeOutUp style=animation-duration:1000ms;animation-delay:0ms;z-index:500;top:80px;left:70px;width:280px;height:160px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;h4 style=&#34;text-align: center; font-size: 18px; font-weight: bold;&#34;&gt;Thank you!&lt;/h4&gt;&lt;p style=&#34;text-align: center;&#34;&gt;We will contact you soon.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;input type=hidden id=lepopup-logic-3oplLWOHvQuyWxe4 value=[]&gt;&lt;/div&gt;&lt;div class=&#34;post-bottom-meta post-bottom-tags post-tags-classic&#34;&gt;&lt;div class=post-bottom-meta-title&gt;&lt;span class=tie-icon-tags aria-hidden=true&gt;&lt;/span&gt;Tags&lt;/div&gt;&lt;span class=tagcloud&gt;&lt;a href=https://www.javacodegeeks.com/tag/openapi-3-0 rel=tag&gt;OpenAPI 3.0&lt;/a&gt; &lt;a href=https://www.javacodegeeks.com/tag/spring-hateoas rel=tag&gt;Spring HATEOAS&lt;/a&gt; &lt;a href=https://www.javacodegeeks.com/tag/swagger-ui rel=tag&gt;Swagger UI&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div id=post-extra-info&gt;&lt;div class=theiaStickySidebar&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=clearfix&gt;&lt;/div&gt;</description>
      <author>Eleftheria Drosopoulou</author>
      <guid>https://www.javacodegeeks.com/2026/06/spring-hateoas-openapi-3-0-why-links-dont-appear-in-swagger-ui.html</guid>
      <pubDate>Tue, 23 Jun 2026 15:49:00 +0000</pubDate>
    </item>
    <item>
      <title>A Guide to Designing APIs for AI Agents in the Age of AI</title>
      <link>https://www.javacodegeeks.com/a-guide-to-designing-apis-for-ai-agents-in-the-age-of-ai.html</link>
      <description>&lt;header class=entry-header-outer&gt;&lt;nav id=breadcrumb&gt;&lt;a href=https://www.javacodegeeks.com/&gt;&lt;span class=tie-icon-home aria-hidden=true&gt;&lt;/span&gt;Home&lt;/a&gt;&lt;em class=delimiter&gt;»&lt;/em&gt;&lt;a href=https://www.javacodegeeks.com/category/software-development&gt;Software Development&lt;/a&gt;&lt;em class=delimiter&gt;»&lt;/em&gt;&lt;span class=current&gt;A Guide to Designing APIs for AI Agents in the Age of AI&lt;/span&gt;&lt;/nav&gt;&lt;div class=entry-header&gt;&lt;span class=post-cat-wrap&gt;&lt;a class=&#34;post-cat tie-cat-15&#34; href=https://www.javacodegeeks.com/category/software-development&gt;Software Development&lt;/a&gt;&lt;/span&gt;&lt;h1 class=&#34;post-title entry-title&#34;&gt;A Guide to Designing APIs for AI Agents in the Age of AI&lt;/h1&gt;&lt;/div&gt;&lt;/header&gt;&lt;div class=&#34;entry-content entry clearfix&#34;&gt;&lt;div class=&#34;stream-item stream-item-above-post-content&#34;&gt;&lt;div class=stream-item-size&gt;&lt;div id=adngin-in-post-0 style=&#34;float:left; margin-right:20px; margin-bottom:10px; width:300px; height:274px;&#34;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;AI agents are changing how modern software systems are designed and consumed. Unlike traditional applications that rely on predictable, human-driven interactions, AI agents operate autonomously, making decisions, calling APIs, chaining multiple steps, and adapting based on the responses they receive.&lt;p&gt;This shift introduces a new reality: APIs are no longer just consumed by frontend apps or backend services; they are increasingly consumed by intelligent systems that reason, iterate, and act without direct human input.&lt;p&gt;As a result, designing APIs for AI agents requires a different mindset. It is not just about exposing data or functionality, but about creating systems that are understandable, predictable, and usable by machines capable of independent decision-making. This article explores some principles and patterns for designing APIs that AI agents can use.&lt;h2 class=wp-block-heading&gt;1. Design APIs as Composable Tools&lt;/h2&gt;&lt;p&gt;AI agents interact with APIs as tools rather than static endpoints. This means each API should represent a single, clearly defined capability that can be combined with others to achieve more complex goals.&lt;p&gt;Instead of building large, multi-purpose endpoints, the focus should be on small, atomic operations such as searching for data, retrieving specific records, or performing a single action. These simpler building blocks make APIs easier for agents to understand and use correctly.&lt;p&gt;This modular approach allows agents to chain calls together dynamically. For example, an agent might search for products, retrieve details for a selected item, and then create an order—all using separate endpoints. Designing APIs this way improves flexibility, reduces ambiguity, and aligns with how agents naturally break down problems into smaller steps.&lt;h2 class=wp-block-heading&gt;2. Build a Strong OpenAPI Contract for AI Agents&lt;/h2&gt;&lt;p&gt;A well-structured OpenAPI specification is one of the most important foundations for building APIs that work effectively with AI agents. It serves as a machine-readable contract that clearly defines what your API can do, how it should be used, and what kind of responses it returns. For AI systems, this structure removes uncertainty and makes it much easier to interact with your services predictably.&lt;p&gt;AI systems rely on OpenAPI specifications to automatically discover available endpoints, understand required parameters and their data types, and validate both request and response structures before making calls. This reduces trial-and-error behavior and allows agents to plan their actions more effectively when interacting with your API.&lt;p&gt;To make your API truly effective, all request and response schemas should be explicitly defined, with no missing or loosely described fields. It is also important to maintain consistent naming conventions and data typing across all endpoints. A precise OpenAPI specification reduces guesswork and enables agents to interact with your API more consistently and with greater accuracy.&lt;h2 class=wp-block-heading&gt;3. Use Clear and Consistent API Design&lt;/h2&gt;&lt;p&gt;Consistency is very important when designing APIs for AI agents. Unlike humans, AI agents do not rely on intuition or guesswork. They depend on clear and repeatable patterns to understand how a system works.&lt;p&gt;To improve usability, APIs should use predictable naming conventions such as &lt;code&gt;getUserOrders&lt;/code&gt; or &lt;code&gt;searchProducts&lt;/code&gt;, maintain consistent field names across all endpoints, and avoid vague or overloaded terms. When APIs follow a consistent structure, agents can more easily generalise from one endpoint to another, improving their ability to explore and use the system effectively.&lt;div style=&#34;display:inline-block; margin: 15px 0;&#34;&gt;&lt;div id=adngin-JavaCodeGeeks_incontent_video-0 style=display:inline-block;&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;h2 class=wp-block-heading&gt;4. Introduce an MCP Server for Agent Integration&lt;/h2&gt;&lt;p&gt;An MCP (&lt;a href=https://www.javacodegeeks.com/building-a-model-context-protocol-mcp-server-with-python.html target=_blank rel=&#34;noreferrer noopener&#34;&gt;Model Context Protocol&lt;/a&gt;) server provides a structured interface between AI agents and your APIs. Instead of exposing raw endpoints directly, it presents them as standardised tools that agents can easily understand and interact with consistently.&lt;p&gt;This approach comes with several important benefits. It simplifies integration with AI frameworks, centralizes context handling, enforces access control and validation, and improves overall system reliability. It also helps reduce complexity when multiple agents or tools are involved in the same workflow.&lt;p&gt;By introducing an MCP layer, you make your API more accessible, organized, and better aligned with how modern AI systems operate. It creates a cleaner separation between raw backend logic and agent-facing capabilities, making the system easier to scale and maintain.&lt;h2 class=wp-block-heading&gt;5. Design for Multi-Step Workflows&lt;/h2&gt;&lt;p&gt;AI agents rarely solve problems in a single API call. Instead, they operate in iterative loops where each response informs the next action. Your API should support this by:&lt;ul class=wp-block-list&gt;&lt;li&gt;returning identifiers for follow-up actions&lt;li&gt;including enough context in each response&lt;li&gt;ensuring endpoints can be chained logically&lt;/ul&gt;&lt;p&gt;For example, a product search endpoint should return product IDs that can be used in a details endpoint. This enables agents to move seamlessly from one step to the next. Designing with workflows in mind ensures that your API supports real-world agent behavior rather than isolated interactions.&lt;h2 class=wp-block-heading&gt;6. Use Well-Defined and Recoverable Error Responses&lt;/h2&gt;&lt;p&gt;Errors are unavoidable when working with AI agents because they operate in dynamic and sometimes unpredictable ways. However, how your API handles these errors can greatly influence how well an agent performs and recovers from failures.&lt;p&gt;Instead of returning vague or generic error messages, your API should provide structured error codes, clear and human-readable explanations, and indicators that show whether the error can be recovered from. It is also helpful to include suggestions that guide the agent toward correcting its input or adjusting its approach.&lt;p&gt;For example, instead of returning a plain message like “Invalid input,” a better response would be a structured format such as:&lt;pre class=brush:javascript,json,plain&gt;{&#xA;  &amp;#34;error&amp;#34;: {&#xA;    &amp;#34;code&amp;#34;: &amp;#34;INVALID_QUERY&amp;#34;,&#xA;    &amp;#34;message&amp;#34;: &amp;#34;The search query cannot be empty.&amp;#34;,&#xA;    &amp;#34;recoverable&amp;#34;: true,&#xA;    &amp;#34;suggestion&amp;#34;: &amp;#34;Provide a keyword or product name in the query field.&amp;#34;&#xA;  }&#xA;}&#xA;&lt;/pre&gt;&lt;p&gt;With this level of clarity, agents can respond more intelligently to failures. They can retry with improved inputs, switch to alternative actions, or adjust their workflow instead of stopping completely. Well-designed error handling transforms mistakes into useful feedback that helps the agent improve its decision-making process.&lt;h2 class=wp-block-heading&gt;7. Guide AI Agents with Clear Workflow Documentation&lt;/h2&gt;&lt;p&gt;Beyond documenting individual endpoints, it is also important to provide higher-level guidance that helps AI agents understand how to use your API in real-world scenarios. Instead of only explaining what each endpoint does, you should also describe how they work together as part of complete workflows.&lt;p&gt;Good documentation should include common usage patterns, typical sequences of API calls, and clear recommendations for what an agent should do next after each action. This helps create a logical flow that agents can follow, rather than forcing them to discover relationships between endpoints through trial and error.&lt;p&gt;For example, after an agent retrieves a list of items from a search endpoint, the documentation can suggest calling a detail endpoint to get more information about a specific item or proceeding directly to an action like creating an order. This kind of guidance reduces ambiguity, improves decision-making, and helps agents interact with your API more efficiently and accurately.&lt;h2 class=wp-block-heading&gt;8. Write Clear Metadata for LLM Understanding&lt;/h2&gt;&lt;p&gt;AI agents rely heavily on metadata and descriptions to understand when and how to use an API. Because of this, metadata is just as important as the API itself, as it helps agents interpret the purpose of each endpoint before making a call. Each endpoint should include a clear name, a concise but meaningful description, detailed parameter explanations, and a proper usage context.&lt;p&gt;Instead of vague descriptions, focus on clarity and intent. For example, rather than saying “Get products,” explain that the endpoint is used to search and retrieve products based on user queries or filters. Well-written metadata improves tool selection, reduces errors, and helps AI agents map user intent to the correct API call more accurately.&lt;p&gt;In addition to in-API metadata, you can provide a &lt;code&gt;/llms.txt&lt;/code&gt; file as a lightweight documentation layer for AI systems, as described at &lt;a href=https://llmstxt.org/ target=_blank rel=&#34;noreferrer noopener&#34;&gt;https://llmstxt.org/&lt;/a&gt;. This file serves as a simple entry point that summarises your API, highlights key endpoints, and guides to help LLMs quickly understand your system.&lt;h2 class=wp-block-heading&gt;9. Design for Reliability, Safety, and Evolution&lt;/h2&gt;&lt;p&gt;AI agents can behave in unpredictable ways because they operate autonomously and may generate repeated calls, unexpected inputs, or unusual sequences of actions. For this reason, your API must be designed to be highly resilient and capable of handling these variations without breaking or producing inconsistent results.&lt;p&gt;To achieve this, endpoints should be made idempotent wherever possible so that repeated requests do not create unintended side effects. Inputs should be strictly validated to prevent invalid or malformed data from affecting system stability. In addition, implementing rate limiting and strong access control helps protect your system from overload or misuse, while detailed logging of interactions supports effective monitoring, debugging, and performance analysis.&lt;p&gt;Your API should also evolve safely and predictably over time. This means using proper versioning strategies, maintaining backward compatibility, and avoiding breaking changes that could disrupt existing agent workflows. A reliable and secure API ensures that AI agents can operate consistently at scale while maintaining stable performance and predictable behavior over time.&lt;h2 class=wp-block-heading&gt;10. Conclusion&lt;/h2&gt;&lt;p&gt;Designing APIs for AI agents requires a shift from traditional thinking to a more dynamic, machine-centred approach. Instead of building APIs solely for human developers, you are now designing systems that intelligent agents will explore, interpret, and use autonomously.&lt;p&gt;The most effective APIs are not just functional—they are structured, descriptive, predictable, and resilient. They provide clear guidance, support multi-step reasoning, and handle uncertainty gracefully.&lt;p&gt;As AI agents continue to grow in capability and adoption, the quality of your API design will play a critical role in how effectively they can interact with your systems. By applying these principles, you can build APIs that are not only usable but truly intelligent-ready.&lt;p&gt;This article explored how to design APIs for AI agents.&lt;/p&gt;&lt;style&gt;.lepopup-progress-60 div.lepopup-progress-t1&gt;div{background-color:#e0e0e0;}.lepopup-progress-60 div.lepopup-progress-t1&gt;div&gt;div{background-color:#bd4070;}.lepopup-progress-60 div.lepopup-progress-t1&gt;div&gt;div{color:#ffffff;}.lepopup-progress-60 div.lepopup-progress-t1&gt;label{color:#444444;}.lepopup-form-60, .lepopup-form-60 *, .lepopup-progress-60 {font-size:15px;color:#444444;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-signature-box span i{font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#555555;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-signature-box,.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;text&#39;],.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;email&#39;],.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;password&#39;],.lepopup-form-60 .lepopup-element div.lepopup-input select,.lepopup-form-60 .lepopup-element div.lepopup-input select option,.lepopup-form-60 .lepopup-element div.lepopup-input textarea{font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#555555;font-style:normal;text-decoration:none;text-align:left;background-color:rgba(255, 255, 255, 0.7);background-image:none;border-width:1px;border-style:solid;border-color:#cccccc;border-radius:0px;box-shadow: inset 0px 0px 15px -7px #000000;}.lepopup-form-60 .lepopup-element div.lepopup-input ::placeholder{color:#555555; opacity: 0.9;} .lepopup-form-60 .lepopup-element div.lepopup-input ::-ms-input-placeholder{color:#555555; opacity: 0.9;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect::-webkit-scrollbar-thumb{background-color:#cccccc;}.lepopup-form-60 .lepopup-element div.lepopup-input&gt;i.lepopup-icon-left, .lepopup-form-60 .lepopup-element div.lepopup-input&gt;i.lepopup-icon-right{font-size:20px;color:#444444;border-radius:0px;}.lepopup-form-60 .lepopup-element .lepopup-button,.lepopup-form-60 .lepopup-element .lepopup-button:visited{font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#ffffff;font-weight:700;font-style:normal;text-decoration:none;text-align:center;background-color:#326693;background-image:none;border-width:1px;border-style:solid;border-color:#326693;border-radius:0px;box-shadow:none;}.lepopup-form-60 .lepopup-element div.lepopup-input .lepopup-imageselect+label{border-width:1px;border-style:solid;border-color:#cccccc;border-radius:0px;box-shadow:none;}.lepopup-form-60 .lepopup-element div.lepopup-input .lepopup-imageselect+label span.lepopup-imageselect-label{font-size:15px;color:#444444;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl:checked+label:after{background-color:rgba(255, 255, 255, 0.7);}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-classic+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-fa-check+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-square+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl+label{background-color:rgba(255, 255, 255, 0.7);border-color:#cccccc;color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-square:checked+label:after{background-color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl:checked+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;checkbox&#39;].lepopup-checkbox-tgl+label:after{background-color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-classic+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-fa-check+label,.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-dot+label{background-color:rgba(255, 255, 255, 0.7);border-color:#cccccc;color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input input[type=&#39;radio&#39;].lepopup-radio-dot:checked+label:after{background-color:#555555;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect&gt;input[type=&#39;checkbox&#39;]+label:hover{background-color:#bd4070;color:#ffffff;}.lepopup-form-60 .lepopup-element div.lepopup-input div.lepopup-multiselect&gt;input[type=&#39;checkbox&#39;]:checked+label{background-color:#a93a65;color:#ffffff;}.lepopup-form-60 .lepopup-element input[type=&#39;checkbox&#39;].lepopup-tile+label, .lepopup-form-60 .lepopup-element input[type=&#39;radio&#39;].lepopup-tile+label {font-size:15px;color:#444444;font-style:normal;text-decoration:none;text-align:center;background-color:#ffffff;background-image:none;border-width:1px;border-style:solid;border-color:#cccccc;border-radius:0px;box-shadow:none;}.lepopup-form-60 .lepopup-element-error{font-size:15px;color:#ffffff;font-style:normal;text-decoration:none;text-align:left;background-color:#d9534f;background-image:none;}.lepopup-form-60 .lepopup-element-2 {background-color:rgba(226, 236, 250, 1);background-image:none;border-width:1px;border-style:solid;border-color:rgba(216, 216, 216, 1);border-radius:3px;box-shadow: 1px 1px 15px -6px #d7e1eb;}.lepopup-form-60 .lepopup-element-3 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:26px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-3 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:26px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-3 .lepopup-element-html-content {min-height:73px;}.lepopup-form-60 .lepopup-element-4 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:19px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-4 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:19px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-4 .lepopup-element-html-content {min-height:23px;}.lepopup-form-60 .lepopup-element-5 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-5 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-5 .lepopup-element-html-content {min-height:24px;}.lepopup-form-60 .lepopup-element-6 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-6 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-6 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-7 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-7 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-7 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-8 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-8 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-8 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-9 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-9 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-9 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-10 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-10 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-10 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-11 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-11 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-11 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-12 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-12 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-12 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-13 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-13 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:15px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-13 .lepopup-element-html-content {min-height:18px;}.lepopup-form-60 .lepopup-element-14 div.lepopup-input .lepopup-icon-left, .lepopup-form-60 .lepopup-element-14 div.lepopup-input .lepopup-icon-right {line-height:36px;}.lepopup-form-60 .lepopup-element-15 div.lepopup-input{height:auto;line-height:1;}.lepopup-form-60 .lepopup-element-16 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:14px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-16 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:14px;color:#333333;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-16 .lepopup-element-html-content {min-height:5px;}.lepopup-form-60 .lepopup-element-19 * {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#333333;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-19 {font-family:&#39;Arial&#39;,&#39;arial&#39;;font-size:13px;color:#333333;font-style:normal;text-decoration:none;text-align:left;background-color:transparent;background-image:none;border-width:1px;border-style:none;border-color:transparent;border-radius:0px;box-shadow:none;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.lepopup-form-60 .lepopup-element-19 .lepopup-element-html-content {min-height:363px;}.lepopup-form-60 .lepopup-element-0 * {font-size:15px;color:#ffffff;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;}.lepopup-form-60 .lepopup-element-0 {font-size:15px;color:#ffffff;font-weight:normal;font-style:normal;text-decoration:none;text-align:left;background-color:#5cb85c;background-image:none;border-width:0px;border-style:solid;border-color:#ccc;border-radius:5px;box-shadow: 1px 1px 15px -6px #000000;padding-top:40px;padding-right:40px;padding-bottom:40px;padding-left:40px;}.lepopup-form-60 .lepopup-element-0 .lepopup-element-html-content {min-height:160px;}&lt;/style&gt;&lt;div class=lepopup-inline style=&#34;margin: 0 auto;&#34;&gt;&lt;div class=&#34;lepopup-form lepopup-form-60 lepopup-form-QnFpYAwS3YfGj7IW lepopup-form-icon-inside lepopup-form-position-middle-right&#34; data-session=0 data-id=QnFpYAwS3YfGj7IW data-form-id=60 data-slug=7lQM6oyWL5bTm5lw data-title=&#34;Under the Post Inline&#34; data-page=1 data-xd=off data-width=820 data-height=430 data-position=middle-right data-esc=off data-enter=on data-disable-scrollbar=off style=display:none;width:820px;height:430px; onclick=event.stopPropagation();&gt;&lt;div class=lepopup-form-inner style=width:820px;height:430px;&gt;&lt;div class=&#34;lepopup-element lepopup-element-2 lepopup-element-rectangle&#34; data-type=rectangle data-top=0 data-left=0 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:501;top:0px;left:0px;width:820px;height:430px;&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-3 lepopup-element-html&#34; data-type=html data-top=7 data-left=10 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:502;top:7px;left:10px;width:797px;height:73px;&gt;&lt;div class=lepopup-element-html-content&gt;Do you want to know how to develop your skillset to become a &lt;span style=&#34;color: #CAB43D; text-shadow: 1px 1px #835D5D;&#34;&gt;Java Rockstar?&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-4 lepopup-element-html&#34; data-type=html data-top=83 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:503;top:83px;left:308px;width:473px;height:23px;&gt;&lt;div class=lepopup-element-html-content&gt;Subscribe to our newsletter to start Rocking &lt;span style=&#34;text-decoration: underline;&#34;&gt;right now!&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-5 lepopup-element-html&#34; data-type=html data-top=107 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:504;top:107px;left:308px;width:473px;height:24px;&gt;&lt;div class=lepopup-element-html-content&gt;To get you started we give you our best selling eBooks for &lt;span style=&#34;color:#e01404; text-shadow: 1px 1px #C99924; font-size: 15px;&#34;&gt;FREE!&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-6 lepopup-element-html&#34; data-type=html data-top=136 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:505;top:136px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;1.&lt;/span&gt; JPA Mini Book&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-7 lepopup-element-html&#34; data-type=html data-top=156 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:506;top:156px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;2.&lt;/span&gt; JVM Troubleshooting Guide&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-8 lepopup-element-html&#34; data-type=html data-top=176 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:507;top:176px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;3.&lt;/span&gt; JUnit Tutorial for Unit Testing&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-9 lepopup-element-html&#34; data-type=html data-top=196 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:508;top:196px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;4.&lt;/span&gt; Java Annotations Tutorial&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-10 lepopup-element-html&#34; data-type=html data-top=216 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:509;top:216px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;5.&lt;/span&gt; Java Interview Questions&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-11 lepopup-element-html&#34; data-type=html data-top=236 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:510;top:236px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;6.&lt;/span&gt; Spring Interview Questions&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-12 lepopup-element-html&#34; data-type=html data-top=256 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:511;top:256px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;span style=&#34;font-weight: bold;&#34;&gt;7.&lt;/span&gt; Android UI Design&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-13 lepopup-element-html&#34; data-type=html data-top=282 data-left=308 data-animation-in=bounceInDown data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:512;top:282px;left:308px;width:473px;height:18px;&gt;&lt;div class=lepopup-element-html-content&gt;and many more ....&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-14&#34; data-type=email data-deps data-id=14 data-top=305 data-left=308 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:513;top:305px;left:308px;width:473px;height:36px;&gt;&lt;div class=lepopup-input&gt;&lt;input type=email name=lepopup-14 class=lepopup-ta-left placeholder=&#34;Enter your e-mail...&#34; autocomplete=email data-default aria-label=&#34;Email Field&#34; oninput=lepopup_input_changed(this); onfocus=lepopup_input_error_hide(this);&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-15&#34; data-type=checkbox data-deps data-id=15 data-top=344 data-left=308 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:514;top:344px;left:308px;width:160px;&gt;&lt;div class=&#34;lepopup-input lepopup-cr-layout-1 lepopup-cr-layout-left&#34;&gt;&lt;div class=&#34;lepopup-cr-container lepopup-cr-container-medium lepopup-cr-container-left&#34;&gt;&lt;div class=lepopup-cr-box&gt;&lt;input class=&#34;lepopup-checkbox lepopup-checkbox-classic lepopup-checkbox-medium&#34; type=checkbox name=lepopup-15[] id=lepopup-checkbox-W1k5CnJwosmCkCwl-14-0 value=on data-default=off onchange=lepopup_input_changed(this);&gt;&lt;label for=lepopup-checkbox-W1k5CnJwosmCkCwl-14-0 onclick=lepopup_input_error_hide(this);&gt;&lt;/label&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-cr-label lepopup-ta-left&#34;&gt;&lt;label for=lepopup-checkbox-W1k5CnJwosmCkCwl-14-0 onclick=lepopup_input_error_hide(this);&gt;&lt;/label&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-16 lepopup-element-html&#34; data-type=html data-top=344 data-left=338 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:515;top:344px;left:338px;width:350px;height:5px;&gt;&lt;div class=lepopup-element-html-content&gt;I agree to the &lt;a href=https://www.javacodegeeks.com/about/terms-of-use target=_blank&gt;Terms&lt;/a&gt; and &lt;a href=https://www.javacodegeeks.com/about/privacy-policy target=_blank&gt;Privacy Policy&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-17&#34; data-type=button data-top=372 data-left=308 data-animation-in=bounceIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:516;top:372px;left:308px;width:85px;height:37px;&gt;&lt;a class=&#34;lepopup-button lepopup-button-zoom-out&#34; href=https://www.javacodegeeks.com/feed/ onclick=&#34;return lepopup_submit(this);&#34; data-label=&#34;Sign up&#34; data-loading=Loading...&gt;&lt;span&gt;Sign up&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-element lepopup-element-19 lepopup-element-html&#34; data-type=html data-top=67 data-left=-15 data-animation-in=fadeIn data-animation-out=fadeOut style=animation-duration:0ms;animation-delay:0ms;z-index:518;top:67px;left:-15px;width:320px;height:363px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;img data-lazyloaded=1 src=https://www.javacodegeeks.com/wp-content/uploads/2015/01/books_promo.png fetchpriority=high decoding=async data-src=https://www.javacodegeeks.com/wp-content/uploads/2015/01/books_promo.png alt width=320 height=363&gt;&lt;noscript&gt;&lt;img fetchpriority=high decoding=async src=https://www.javacodegeeks.com/wp-content/uploads/2015/01/books_promo.png alt width=320 height=363&gt;&lt;/noscript&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;lepopup-form lepopup-form-60 lepopup-form-QnFpYAwS3YfGj7IW lepopup-form-icon-inside lepopup-form-position-middle-right&#34; data-session=0 data-id=QnFpYAwS3YfGj7IW data-form-id=60 data-slug=7lQM6oyWL5bTm5lw data-title=&#34;Under the Post Inline&#34; data-page=confirmation data-xd=off data-width=420 data-height=320 data-position=middle-right data-esc=off data-enter=on data-disable-scrollbar=off style=display:none;width:420px;height:320px; onclick=event.stopPropagation();&gt;&lt;div class=lepopup-form-inner style=width:420px;height:320px;&gt;&lt;div class=&#34;lepopup-element lepopup-element-0 lepopup-element-html&#34; data-type=html data-top=80 data-left=70 data-animation-in=bounceInDown data-animation-out=fadeOutUp style=animation-duration:1000ms;animation-delay:0ms;z-index:500;top:80px;left:70px;width:280px;height:160px;&gt;&lt;div class=lepopup-element-html-content&gt;&lt;h4 style=&#34;text-align: center; font-size: 18px; font-weight: bold;&#34;&gt;Thank you!&lt;/h4&gt;&lt;p style=&#34;text-align: center;&#34;&gt;We will contact you soon.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;input type=hidden id=lepopup-logic-QnFpYAwS3YfGj7IW value=[]&gt;&lt;/div&gt;&lt;div class=&#34;post-bottom-meta post-bottom-tags post-tags-classic&#34;&gt;&lt;div class=post-bottom-meta-title&gt;&lt;span class=tie-icon-tags aria-hidden=true&gt;&lt;/span&gt;Tags&lt;/div&gt;&lt;span class=tagcloud&gt;&lt;a href=https://www.javacodegeeks.com/tag/ai rel=tag&gt;AI&lt;/a&gt; &lt;a href=https://www.javacodegeeks.com/tag/ai-agents rel=tag&gt;AI Agents&lt;/a&gt; &lt;a href=https://www.javacodegeeks.com/tag/api-design rel=tag&gt;API Design&lt;/a&gt; &lt;a href=https://www.javacodegeeks.com/tag/llms rel=tag&gt;LLMs&lt;/a&gt; &lt;a href=https://www.javacodegeeks.com/tag/machine-learning rel=tag&gt;Machine Learning&lt;/a&gt; &lt;a href=https://www.javacodegeeks.com/tag/software-architecture rel=tag&gt;Software Architecture&lt;/a&gt; &lt;a href=https://www.javacodegeeks.com/tag/system-design rel=tag&gt;System Design&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div id=post-extra-info&gt;&lt;div class=theiaStickySidebar&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=clearfix&gt;&lt;/div&gt;</description>
      <author>Omozegie Aziegbe</author>
      <guid>https://www.javacodegeeks.com/a-guide-to-designing-apis-for-ai-agents-in-the-age-of-ai.html</guid>
      <pubDate>Tue, 23 Jun 2026 12:41:31 +0000</pubDate>
    </item>
  </channel>
</rss>