en DZone Java Zone https://dzone.com/java Recent posts in Java on DZone.com Taming the JVM Latency Monster https://dzone.com/articles/taming-the-jvm-latency-monster <h1>Attention Required! | Cloudflare</h1><div id="cf-wrapper"> <p>Please enable cookies.</p> <div id="cf-error-details"> <p> <h2><span data-translate="unable_to_access">You are unable to access</span> dzone.com</h2> </p> <div> <div> <div> <h2 data-translate="blocked_why_headline">Why have I been blocked?</h2> <p data-translate="blocked_why_detail">This website is using a security service to protect itself from online attacks. The action you just performed triggered the security solution. There are several actions that could trigger this block including submitting a certain word or phrase, a SQL command or malformed data.</p> </div> <div> <h2 data-translate="blocked_resolve_headline">What can I do to resolve this?</h2> <p data-translate="blocked_resolve_detail">You can email the site owner to let them know you were blocked. Please include what you were doing when this page came up and the Cloudflare Ray ID found at the bottom of this page.</p> </div> </div> </div> <p> <span>Cloudflare Ray ID: <strong>9e29bc7688bd07da</strong></span> <span>•</span> <span id="cf-footer-item-ip"> Your IP: <span id="cf-footer-ip">5.1.64.146</span> <span>•</span> </span> <span><span>Performance &amp; security by</span> <a href="https://www.cloudflare.com/5xx-error-landing" id="brand_link" rel="noopener noreferrer" target="_blank">Cloudflare</a></span> </p> </div> </div><br><span style='font: #ff0000'>Generated by <a href='https://github.com/andreskrey/readability.php'>Readability.php</a>.</span> Thu, 26 Mar 2026 20:00:00 GMT https://dzone.com/articles/3639529 Theo Ezell Automating Maven Dependency Upgrades Using AI https://dzone.com/articles/automating-maven-dependency-upgrades-using-ai <h1>Attention Required! | Cloudflare</h1><div id="cf-wrapper"> <p>Please enable cookies.</p> <div id="cf-error-details"> <p> <h2><span data-translate="unable_to_access">You are unable to access</span> dzone.com</h2> </p> <div> <div> <div> <h2 data-translate="blocked_why_headline">Why have I been blocked?</h2> <p data-translate="blocked_why_detail">This website is using a security service to protect itself from online attacks. The action you just performed triggered the security solution. There are several actions that could trigger this block including submitting a certain word or phrase, a SQL command or malformed data.</p> </div> <div> <h2 data-translate="blocked_resolve_headline">What can I do to resolve this?</h2> <p data-translate="blocked_resolve_detail">You can email the site owner to let them know you were blocked. Please include what you were doing when this page came up and the Cloudflare Ray ID found at the bottom of this page.</p> </div> </div> </div> <p> <span>Cloudflare Ray ID: <strong>9e29bc78890b9748</strong></span> <span>•</span> <span id="cf-footer-item-ip"> Your IP: <span id="cf-footer-ip">5.1.64.146</span> <span>•</span> </span> <span><span>Performance &amp; security by</span> <a href="https://www.cloudflare.com/5xx-error-landing" id="brand_link" rel="noopener noreferrer" target="_blank">Cloudflare</a></span> </p> </div> </div><br><span style='font: #ff0000'>Generated by <a href='https://github.com/andreskrey/readability.php'>Readability.php</a>.</span> Thu, 26 Mar 2026 19:00:00 GMT https://dzone.com/articles/3640454 Sravan Reddy Kathi Data Driven API Testing in Java With REST Assured and TestNG: Part 4 https://dzone.com/articles/data-driven-api-testing-java-rest-assured-part-4 <h1>Attention Required! | Cloudflare</h1><div id="cf-wrapper"> <p>Please enable cookies.</p> <div id="cf-error-details"> <p> <h2><span data-translate="unable_to_access">You are unable to access</span> dzone.com</h2> </p> <div> <div> <div> <h2 data-translate="blocked_why_headline">Why have I been blocked?</h2> <p data-translate="blocked_why_detail">This website is using a security service to protect itself from online attacks. The action you just performed triggered the security solution. There are several actions that could trigger this block including submitting a certain word or phrase, a SQL command or malformed data.</p> </div> <div> <h2 data-translate="blocked_resolve_headline">What can I do to resolve this?</h2> <p data-translate="blocked_resolve_detail">You can email the site owner to let them know you were blocked. Please include what you were doing when this page came up and the Cloudflare Ray ID found at the bottom of this page.</p> </div> </div> </div> <p> <span>Cloudflare Ray ID: <strong>9e29bc7a89fce282</strong></span> <span>•</span> <span id="cf-footer-item-ip"> Your IP: <span id="cf-footer-ip">5.1.64.146</span> <span>•</span> </span> <span><span>Performance &amp; security by</span> <a href="https://www.cloudflare.com/5xx-error-landing" id="brand_link" rel="noopener noreferrer" target="_blank">Cloudflare</a></span> </p> </div> </div><br><span style='font: #ff0000'>Generated by <a href='https://github.com/andreskrey/readability.php'>Readability.php</a>.</span> Thu, 26 Mar 2026 12:00:00 GMT https://dzone.com/articles/3641501 Faisal Khatri Data-Driven API Testing in Java With REST Assured and TestNG: Part 3 https://dzone.com/articles/data-driven-api-testing-java-rest-assured-part-3 <h1>Attention Required! | Cloudflare</h1><div id="cf-wrapper"> <p>Please enable cookies.</p> <div id="cf-error-details"> <p> <h2><span data-translate="unable_to_access">You are unable to access</span> dzone.com</h2> </p> <div> <div> <div> <h2 data-translate="blocked_why_headline">Why have I been blocked?</h2> <p data-translate="blocked_why_detail">This website is using a security service to protect itself from online attacks. The action you just performed triggered the security solution. There are several actions that could trigger this block including submitting a certain word or phrase, a SQL command or malformed data.</p> </div> <div> <h2 data-translate="blocked_resolve_headline">What can I do to resolve this?</h2> <p data-translate="blocked_resolve_detail">You can email the site owner to let them know you were blocked. Please include what you were doing when this page came up and the Cloudflare Ray ID found at the bottom of this page.</p> </div> </div> </div> <p> <span>Cloudflare Ray ID: <strong>9e22a9dd2ec48e2c</strong></span> <span>•</span> <span id="cf-footer-item-ip"> Your IP: <span id="cf-footer-ip">5.1.64.146</span> <span>•</span> </span> <span><span>Performance &amp; security by</span> <a href="https://www.cloudflare.com/5xx-error-landing" id="brand_link" rel="noopener noreferrer" target="_blank">Cloudflare</a></span> </p> </div> </div><br><span style='font: #ff0000'>Generated by <a href='https://github.com/andreskrey/readability.php'>Readability.php</a>.</span> Wed, 25 Mar 2026 14:30:00 GMT https://dzone.com/articles/3641500 Faisal Khatri Data-Driven API Testing in Java With REST Assured and TestNG: Part 2 https://dzone.com/articles/java-api-testing-rest-assured-testng-part-2 <h1>Attention Required! | Cloudflare</h1><div id="cf-wrapper"> <p>Please enable cookies.</p> <div id="cf-error-details"> <p> <h2><span data-translate="unable_to_access">You are unable to access</span> dzone.com</h2> </p> <div> <div> <div> <h2 data-translate="blocked_why_headline">Why have I been blocked?</h2> <p data-translate="blocked_why_detail">This website is using a security service to protect itself from online attacks. The action you just performed triggered the security solution. There are several actions that could trigger this block including submitting a certain word or phrase, a SQL command or malformed data.</p> </div> <div> <h2 data-translate="blocked_resolve_headline">What can I do to resolve this?</h2> <p data-translate="blocked_resolve_detail">You can email the site owner to let them know you were blocked. Please include what you were doing when this page came up and the Cloudflare Ray ID found at the bottom of this page.</p> </div> </div> </div> <p> <span>Cloudflare Ray ID: <strong>9e22a9df2dff1e45</strong></span> <span>•</span> <span id="cf-footer-item-ip"> Your IP: <span id="cf-footer-ip">5.1.64.146</span> <span>•</span> </span> <span><span>Performance &amp; security by</span> <a href="https://www.cloudflare.com/5xx-error-landing" id="brand_link" rel="noopener noreferrer" target="_blank">Cloudflare</a></span> </p> </div> </div><br><span style='font: #ff0000'>Generated by <a href='https://github.com/andreskrey/readability.php'>Readability.php</a>.</span> Tue, 24 Mar 2026 17:00:00 GMT https://dzone.com/articles/3641498 Faisal Khatri Scalable Cloud-Native Java Architecture With Microservices and Serverless https://dzone.com/articles/cloud-native-java-microservices-serverless <h1>Attention Required! | Cloudflare</h1><div id="cf-wrapper"> <p>Please enable cookies.</p> <div id="cf-error-details"> <p> <h2><span data-translate="unable_to_access">You are unable to access</span> dzone.com</h2> </p> <div> <div> <div> <h2 data-translate="blocked_why_headline">Why have I been blocked?</h2> <p data-translate="blocked_why_detail">This website is using a security service to protect itself from online attacks. The action you just performed triggered the security solution. There are several actions that could trigger this block including submitting a certain word or phrase, a SQL command or malformed data.</p> </div> <div> <h2 data-translate="blocked_resolve_headline">What can I do to resolve this?</h2> <p data-translate="blocked_resolve_detail">You can email the site owner to let them know you were blocked. Please include what you were doing when this page came up and the Cloudflare Ray ID found at the bottom of this page.</p> </div> </div> </div> <p> <span>Cloudflare Ray ID: <strong>9df60f34fc70340d</strong></span> <span>•</span> <span id="cf-footer-item-ip"> Your IP: <span id="cf-footer-ip">5.1.64.146</span> <span>•</span> </span> <span><span>Performance &amp; security by</span> <a href="https://www.cloudflare.com/5xx-error-landing" id="brand_link" rel="noopener noreferrer" target="_blank">Cloudflare</a></span> </p> </div> </div><br><span style='font: #ff0000'>Generated by <a href='https://github.com/andreskrey/readability.php'>Readability.php</a>.</span> Fri, 20 Mar 2026 14:00:00 GMT https://dzone.com/articles/3639338 Harris Anderson Java Microservices (SCS) vs. Spring Modulith https://dzone.com/articles/java-microservicesscs-vs-spring-modulith <h1>Attention Required! | Cloudflare</h1><div id="cf-wrapper"> <p>Please enable cookies.</p> <div id="cf-error-details"> <p> <h2><span data-translate="unable_to_access">You are unable to access</span> dzone.com</h2> </p> <div> <div> <div> <h2 data-translate="blocked_why_headline">Why have I been blocked?</h2> <p data-translate="blocked_why_detail">This website is using a security service to protect itself from online attacks. The action you just performed triggered the security solution. There are several actions that could trigger this block including submitting a certain word or phrase, a SQL command or malformed data.</p> </div> <div> <h2 data-translate="blocked_resolve_headline">What can I do to resolve this?</h2> <p data-translate="blocked_resolve_detail">You can email the site owner to let them know you were blocked. Please include what you were doing when this page came up and the Cloudflare Ray ID found at the bottom of this page.</p> </div> </div> </div> <p> <span>Cloudflare Ray ID: <strong>9df60f36f85b39be</strong></span> <span>•</span> <span id="cf-footer-item-ip"> Your IP: <span id="cf-footer-ip">5.1.64.146</span> <span>•</span> </span> <span><span>Performance &amp; security by</span> <a href="https://www.cloudflare.com/5xx-error-landing" id="brand_link" rel="noopener noreferrer" target="_blank">Cloudflare</a></span> </p> </div> </div><br><span style='font: #ff0000'>Generated by <a href='https://github.com/andreskrey/readability.php'>Readability.php</a>.</span> Wed, 18 Mar 2026 20:00:00 GMT https://dzone.com/articles/3629470 Sven Loesekann Zero-Cost AI with Java https://dzone.com/articles/zero-cost-ai-with-java-1 <h1>Attention Required! | Cloudflare</h1><div id="cf-wrapper"> <p>Please enable cookies.</p> <div id="cf-error-details"> <p> <h2><span data-translate="unable_to_access">You are unable to access</span> dzone.com</h2> </p> <div> <div> <div> <h2 data-translate="blocked_why_headline">Why have I been blocked?</h2> <p data-translate="blocked_why_detail">This website is using a security service to protect itself from online attacks. The action you just performed triggered the security solution. There are several actions that could trigger this block including submitting a certain word or phrase, a SQL command or malformed data.</p> </div> <div> <h2 data-translate="blocked_resolve_headline">What can I do to resolve this?</h2> <p data-translate="blocked_resolve_detail">You can email the site owner to let them know you were blocked. Please include what you were doing when this page came up and the Cloudflare Ray ID found at the bottom of this page.</p> </div> </div> </div> <p> <span>Cloudflare Ray ID: <strong>9df60f38fcc91e68</strong></span> <span>•</span> <span id="cf-footer-item-ip"> Your IP: <span id="cf-footer-ip">5.1.64.146</span> <span>•</span> </span> <span><span>Performance &amp; security by</span> <a href="https://www.cloudflare.com/5xx-error-landing" id="brand_link" rel="noopener noreferrer" target="_blank">Cloudflare</a></span> </p> </div> </div><br><span style='font: #ff0000'>Generated by <a href='https://github.com/andreskrey/readability.php'>Readability.php</a>.</span> Wed, 18 Mar 2026 19:00:00 GMT https://dzone.com/articles/3639155 Fernando Boaglio Stranger Things in Java: Enum Types https://dzone.com/articles/stranger-things-in-java-enum-types <h1>Attention Required! | Cloudflare</h1><div id="cf-wrapper"> <p>Please enable cookies.</p> <div id="cf-error-details"> <p> <h2><span data-translate="unable_to_access">You are unable to access</span> dzone.com</h2> </p> <div> <div> <div> <h2 data-translate="blocked_why_headline">Why have I been blocked?</h2> <p data-translate="blocked_why_detail">This website is using a security service to protect itself from online attacks. The action you just performed triggered the security solution. There are several actions that could trigger this block including submitting a certain word or phrase, a SQL command or malformed data.</p> </div> <div> <h2 data-translate="blocked_resolve_headline">What can I do to resolve this?</h2> <p data-translate="blocked_resolve_detail">You can email the site owner to let them know you were blocked. Please include what you were doing when this page came up and the Cloudflare Ray ID found at the bottom of this page.</p> </div> </div> </div> <p> <span>Cloudflare Ray ID: <strong>9ddb9eb1cd128ab5</strong></span> <span>•</span> <span id="cf-footer-item-ip"> Your IP: <span id="cf-footer-ip">5.1.64.146</span> <span>•</span> </span> <span><span>Performance &amp; security by</span> <a href="https://www.cloudflare.com/5xx-error-landing" id="brand_link" rel="noopener noreferrer" target="_blank">Cloudflare</a></span> </p> </div> </div><br><span style='font: #ff0000'>Generated by <a href='https://github.com/andreskrey/readability.php'>Readability.php</a>.</span> Mon, 16 Mar 2026 13:00:09 GMT https://dzone.com/articles/3621156 Claudio De Sio Cesari Extending Java Libraries with Service Loader https://dzone.com/articles/extending-java-libraries-with-service-loader <h1>Attention Required! | Cloudflare</h1><div id="cf-wrapper"> <p>Please enable cookies.</p> <div id="cf-error-details"> <p> <h2><span data-translate="unable_to_access">You are unable to access</span> dzone.com</h2> </p> <div> <div> <div> <h2 data-translate="blocked_why_headline">Why have I been blocked?</h2> <p data-translate="blocked_why_detail">This website is using a security service to protect itself from online attacks. The action you just performed triggered the security solution. There are several actions that could trigger this block including submitting a certain word or phrase, a SQL command or malformed data.</p> </div> <div> <h2 data-translate="blocked_resolve_headline">What can I do to resolve this?</h2> <p data-translate="blocked_resolve_detail">You can email the site owner to let them know you were blocked. Please include what you were doing when this page came up and the Cloudflare Ray ID found at the bottom of this page.</p> </div> </div> </div> <p> <span>Cloudflare Ray ID: <strong>9dca07b79da2c614</strong></span> <span>•</span> <span id="cf-footer-item-ip"> Your IP: <span id="cf-footer-ip">5.1.64.146</span> <span>•</span> </span> <span><span>Performance &amp; security by</span> <a href="https://www.cloudflare.com/5xx-error-landing" id="brand_link" rel="noopener noreferrer" target="_blank">Cloudflare</a></span> </p> </div> </div><br><span style='font: #ff0000'>Generated by <a href='https://github.com/andreskrey/readability.php'>Readability.php</a>.</span> Fri, 13 Mar 2026 17:00:07 GMT https://dzone.com/articles/3636470 Dominik Przybysz What's New in Java 25: Key Changes From Java 21 https://dzone.com/articles/java-25-whats-new-changes-from-java-21 <h1>Attention Required! | Cloudflare</h1><div id="cf-wrapper"> <p>Please enable cookies.</p> <div id="cf-error-details"> <p> <h2><span data-translate="unable_to_access">You are unable to access</span> dzone.com</h2> </p> <div> <div> <div> <h2 data-translate="blocked_why_headline">Why have I been blocked?</h2> <p data-translate="blocked_why_detail">This website is using a security service to protect itself from online attacks. The action you just performed triggered the security solution. There are several actions that could trigger this block including submitting a certain word or phrase, a SQL command or malformed data.</p> </div> <div> <h2 data-translate="blocked_resolve_headline">What can I do to resolve this?</h2> <p data-translate="blocked_resolve_detail">You can email the site owner to let them know you were blocked. Please include what you were doing when this page came up and the Cloudflare Ray ID found at the bottom of this page.</p> </div> </div> </div> <p> <span>Cloudflare Ray ID: <strong>9db7d1da8fc9dbbb</strong></span> <span>•</span> <span id="cf-footer-item-ip"> Your IP: <span id="cf-footer-ip">5.1.64.146</span> <span>•</span> </span> <span><span>Performance &amp; security by</span> <a href="https://www.cloudflare.com/5xx-error-landing" id="brand_link" rel="noopener noreferrer" target="_blank">Cloudflare</a></span> </p> </div> </div><br><span style='font: #ff0000'>Generated by <a href='https://github.com/andreskrey/readability.php'>Readability.php</a>.</span> Thu, 12 Mar 2026 17:00:00 GMT https://dzone.com/articles/3640379 Gunter Rotsaert Unblocking a Failed Solr 5 to Solr 8 Migration in a Large-Scale Ads Retrieval System https://dzone.com/articles/solr5-to-solr8-migration-ads-system <h1>Attention Required! | Cloudflare</h1><div id="cf-wrapper"> <p>Please enable cookies.</p> <div id="cf-error-details"> <p> <h2><span data-translate="unable_to_access">You are unable to access</span> dzone.com</h2> </p> <div> <div> <div> <h2 data-translate="blocked_why_headline">Why have I been blocked?</h2> <p data-translate="blocked_why_detail">This website is using a security service to protect itself from online attacks. The action you just performed triggered the security solution. There are several actions that could trigger this block including submitting a certain word or phrase, a SQL command or malformed data.</p> </div> <div> <h2 data-translate="blocked_resolve_headline">What can I do to resolve this?</h2> <p data-translate="blocked_resolve_detail">You can email the site owner to let them know you were blocked. Please include what you were doing when this page came up and the Cloudflare Ray ID found at the bottom of this page.</p> </div> </div> </div> <p> <span>Cloudflare Ray ID: <strong>9da6e820be00996f</strong></span> <span>•</span> <span id="cf-footer-item-ip"> Your IP: <span id="cf-footer-ip">5.1.64.146</span> <span>•</span> </span> <span><span>Performance &amp; security by</span> <a href="https://www.cloudflare.com/5xx-error-landing" id="brand_link" rel="noopener noreferrer" target="_blank">Cloudflare</a></span> </p> </div> </div><br><span style='font: #ff0000'>Generated by <a href='https://github.com/andreskrey/readability.php'>Readability.php</a>.</span> Tue, 10 Mar 2026 18:00:00 GMT https://dzone.com/articles/3638347 Parveen Saini Square, SumUp, Shopify: Data Streaming for Real-Time Point-of-Sale (POS) https://dzone.com/articles/square-sumup-shopify-data-streaming-for-real-time <h1>Attention Required! | Cloudflare</h1><div id="cf-wrapper"> <p>Please enable cookies.</p> <div id="cf-error-details"> <p> <h2><span data-translate="unable_to_access">You are unable to access</span> dzone.com</h2> </p> <div> <div> <div> <h2 data-translate="blocked_why_headline">Why have I been blocked?</h2> <p data-translate="blocked_why_detail">This website is using a security service to protect itself from online attacks. The action you just performed triggered the security solution. There are several actions that could trigger this block including submitting a certain word or phrase, a SQL command or malformed data.</p> </div> <div> <h2 data-translate="blocked_resolve_headline">What can I do to resolve this?</h2> <p data-translate="blocked_resolve_detail">You can email the site owner to let them know you were blocked. Please include what you were doing when this page came up and the Cloudflare Ray ID found at the bottom of this page.</p> </div> </div> </div> <p> <span>Cloudflare Ray ID: <strong>9da6e822cae637f1</strong></span> <span>•</span> <span id="cf-footer-item-ip"> Your IP: <span id="cf-footer-ip">5.1.64.146</span> <span>•</span> </span> <span><span>Performance &amp; security by</span> <a href="https://www.cloudflare.com/5xx-error-landing" id="brand_link" rel="noopener noreferrer" target="_blank">Cloudflare</a></span> </p> </div> </div><br><span style='font: #ff0000'>Generated by <a href='https://github.com/andreskrey/readability.php'>Readability.php</a>.</span> Mon, 09 Mar 2026 14:00:00 GMT https://dzone.com/articles/3636548 Kai Wähner Building a Java 17-Compatible TLD Generator for Legacy JSP Tag Libraries https://dzone.com/articles/java17-tld-generator-legacy-jsp <img src="https://dz2cdn1.dzone.com/storage/article-thumb/18897431-thumb.jpg" /><h1>Java 17-Compatible TLD Generator for Legacy JSP Tag Library</h1><div> <div><h2><strong><span>When TLD Generation Tooling Falls Behind Java 17</span></strong></h2> <p><span>The vulnerabilities introduced by upgrades to the Java platform tend not to lie in the application code itself, but rather in the ecosystem of build-time tools that enterprise systems rely on. This was made clear by a migration to Java 17, in which a long-standing dependency on TldDoclet to generate Tag Library Descriptor (TLD) was compromised. </span></p> <p><span>TldDoclet, a widely used tool for generating TLD metadata from Java tag handler classes, is no longer supplied or compatible with current Java versions. The effect of this gap was not so obvious. The application itself compiled and executed well with </span><a href="https://dzone.com/articles/features-of-java-17"><span>Java 17</span></a><span>, and the underlying JSP tag handlers remained functional. But TLD generation did not come up with a congenial mechanism, consequently placing a hard blocker late in the build. What once was a constant and unseen component of the toolchain turned into a migration issue with a high risk.</span></p> <p><span>Another solution was to rewrite all custom tags to use .tag files, which was technically feasible but operationally impractical. The system contained more than 700 custom tags, scattered across more than 6,000 production files, spanning years of production experience and implicit contracts that depended on several teams. Massive rewrites at this tier come with a great deal of regression risk, extended validation, and unpredictability that large organizations often cannot afford. This paper explains the origins of these constraints that prompted the design and development of a custom, annotation-based TLD generator, which is compatible with both Java versions, including Java 17, and none of the existing JSP tag libraries are altered. It will not focus on the replacement of JSP or tag libraries, but rather on bridging a tooling gap that remains in the promotion of modern Java, both in the context of the realities of large and long-lived enterprise codebases.</span></p> <h2><strong><span>The Hidden Cost of Abandoned TLD Generation Tooling</span></strong></h2> <p><span>TldDoclet handled a little yet very important issue, viz., to locate the metadata within Amazon Java tag handler classes and automatically create valid TLD files. The functions have, over time, been incorporated into the full build pipelines of many enterprise systems, in most cases without active maintenance or inspection. That dependence has been intangible ever since Java versions had not acquired much speed, and the backward compatibility assumption had been introduced. </span></p> <p><span>With Java 9 and later releases, this assumption no longer holds. The </span><a href="https://dzone.com/articles/how-to-use-java-modules-to-build-a-spring-boot-app"><span>Java Platform Module System</span></a><span> and changes to compiler APIs, limitations on the use of reflection and doclets, among others, were fundamental changes that transformed the landscape on which the TldDoclet tools would operate. To a large extent, TldDoclet must be modified in order to be able to make use of Java 17, as old-fashioned doclet APIs and classpath behavior no longer work with Java 17 anyway.</span></p> <p><span>There is scarcely any such negligence regarding the cost of a tool. It was due to the inability of a TLD generator to obtain the desired results in this case that led to a re-shift in thinking in terms of the generation and validation of tag metadata. The building failures were late in the pipeline, as they were already mostly done with the migration work, and the building failures were by then a point in the architecture decision rather than a mechanical upgrade. </span></p> <p><span>At the enterprise scale, these situations also give rise to unwanted requirements, such as halting Java version upgrades, internal maintenance of obsolete tools, or high-risk refactorings that provide no business value. The challenge was, then, not only to rid herself of TldDoclet, but to do it such that they are caused with minimal uproar, which will be sustainable as long as the next iterations of Java will persist.</span></p> <h2><strong><span>Why Rewriting .tag Files Was Not a Viable Option</span></strong></h2> <p><span>From a modern </span><a href="https://dzone.com/articles/why-jakarta-ee-matters-enterprise-java"><span>Jakarta perspective</span></a><span>, tag files are a clean and supported way to define custom JSP tags. For small systems or greenfield projects, migrating to .tag files can be an attractive solution. In large enterprise systems, however, the cost profile is very different. The application in question contained <strong>hundreds of custom tags</strong>, many with complex attribute definitions and custom data types. These tags were referenced across thousands of JSP files, often with implicit assumptions about attribute behavior that were not fully documented. Rewriting these tags would have required coordinated changes across multiple teams, extensive regression testing, and prolonged stabilization periods.</span></p> <p><span>More importantly, the migration effort was not driven by a desire to modernize the presentation layer, but by a Java platform upgrade. Introducing widespread functional changes unrelated to the original goal would have increased risk without delivering proportional value. In regulated or business-critical systems, this level of uncertainty is often unacceptable. The guiding constraint, therefore, was clear: <strong>existing JSPs and tag handlers had to remain unchanged</strong>. Any solution that required widespread rewrites was considered non-viable, regardless of its theoretical elegance.</span></p> <p><span>From a modern Jakarta perspective, .tag files give a subtle and authorized way of formulating custom JSP tags. In the case of small systems or greenfield projects, the temptation to migrate to .tag files may become viable. But at very large-scale enterprise systems, the profile is quite different. The application under question had hundreds of custom tags, many of which contained the complex definition of the attributes and custom data types. The tags were referenced in thousands of JSP files only half as often, due to implicit assumptions about the behavior of unspecified attributes. It would have required both cross-functional coordination and extensive regression testing, as well as an extended shelf life, to reimplement these tags.</span></p> <p><span>A desire to modernize the presentation layer was not the purpose of undertaking the migration exercise, but rather a Java platform upgrade. The threat of making pervasive functional modifications that were unrelated to the original rationale would have been greater when there was not a corresponding value increment. Uncertainties of this kind are not allowed among regulated or business-critical systems. The motivation force was very self-evident, though: the very existence of JSPs and tag handlers could not be limited. A solution that required a wholesale overhaul was considered, in any case, non-viable regardless of its theoretical loveliness.</span></p> <h2><strong><span>Defining the Design Goals for a Replacement TLD Generator</span></strong></h2> <p><span>It was not supposed to be feature-to-feature, but a replacement under these constraints that would suit modern realities in the Java world and business requirements. Among the basic design goals, which were also formulated at the initial stages, the following are:</span></p> <ul> <li><span><strong>Java version independence</strong>: The solution should be compatible with Java 17 and all prior versions of Java, without relying on deprecated </span><a href="https://dzone.com/articles/everything-you-should-know-about-apis"><span>APIs</span></a><span>.</span></li> <li><strong>Zero JSP change</strong>: Base Existing JSP program and tag usages do not have to be changed.</li> <li><strong>Accurate TLD compatibility</strong>: Built TLD files must be the same as the old descriptors without semantic differences.</li> <li><strong>Integration of builds</strong>: Build TLD will be added to the existing build pipeline.</li> <li><strong>Scalability</strong>: The solution must have the capacity to serve hundreds of tags and thousand files.</li> </ul> <p><span>These targets removed the heavy-exercise reflection run-time solutions and favoured a deterministic build-time model with explicit metadata.</span></p> <h2><strong><span>Using Annotations to Model Tag and Attribute Metadata</span></strong></h2> <p><span>The solution essentially includes an annotation-based metadata model. Tag and attribute information is provided as explicit custom annotations rather than as output from Javadoc parsing or doclet APIs.</span></p> <p><span>Higher still, a tag handler class is annotated with @Tag, which stores tag-level information, such as the tag name. The individual attributes are modeled with the assistance of the annotations as the @Attribute on the setter methods level primarily, which is one way of implementing JSP tags.</span></p> <p><span>An annotation is a capture of each annotation attribute, which captures:</span></p> <ul> <li>Attribute name</li> <li>The attribute may be compulsory or not.</li> <li>The attribute type</li> <li>Metadata expression: runtime support.</li> </ul> <p><span>One of the more complex aspects of this type of approach is type resolution. The names of types are not most often physical primitives (or strings), but domain types of a custom type. The generator is not entirely dependent on reflection; however, it exploits a symbol and type resolver, which is used depending on compiled class files to arrive at the conclusion of the appropriate nature of attributes on module boundaries.</span></p> <p><span>The explicit annotation model puts the developer intent rather than the tooling heuristics in the metadata and makes the metadata more explicit, maintainable, and less delicate due to the parsing logic of the metadata.</span></p> <h2><strong><span>Build-Time Class Scanning in a Modern Java Environment</span></strong></h2> <p><span>To keep up with current Java, the generator is entirely build-time, that is, it scans compiled class files and not source code. The generation stage is carried out as part of a Maven phase and coordinated by an Ant task that can be easily integrated with an existing Jenkins pipeline.</span></p> <p><span>Compiled classes have a number of benefits:</span></p> <ul> <li>Java compatibility: Compatibility across Java versions.</li> <li>Accurate type resolution</li> <li>No reliance on the outdated compiler or documentation APIs.</li> </ul> <p><span>The generator first searches the corresponding classpath and purports the classes that are annotated with the annotation of Tag, analyzes method annotations that have been annotated, resolves attribute metadata, and builds the corresponding TLD representation in a deterministic manner.</span></p> <p><span>Since the process uses a bytecode format and annotations, there is no reason it should be affected by changes to the source format or documentation style.</span></p> <h2><strong><span>Generating Deterministic and Backward-Compatible TLD Files</span></strong></h2> <p><span>One of the most important conditions was that the generated TLD files had to match the legacy descriptors. This contains tag names, attribute definitions, ordering, and the namespace declaration. Even the slightest variations might lead to some unexpected behaviour or make validation harder in enterprise settings.</span></p> <p><span>The generator uses a controlled, deterministic process that generates TLD files to be compatible. The results are compared to the available descriptors to establish the semantic equivalence. As a matter of fact, the TLDs generated coincided with the legacy files with zero difference, and thus, they could be dropped and left to rest without any additional modifications.</span></p> <p><span>This fidelity was a requirement of adoption. Teams might believe that the new generator made no difference, only the means by which metadata was created.</span></p> <h2><strong><span>Integrating the Generator Into Existing CI/CD Pipelines</span></strong></h2> <p><span>The generator is included in the typical construction, and it is automatically run when CI builds are being done. Its requirement to run on compiled classes as well as to generate artifacts identical to those generated previously meant that it did not need much modification to existing pipelines.</span></p> <p><span>This combination meant that the generation of TLD remained:</span></p> <ul> <li>Automated</li> <li>Repeatable</li> <li>Open to tag consumers.</li> </ul> <p><span>The generator acts like any other build step, which, in terms of CI/CD, eases the cognitive and operational load of the migration.</span></p> <h2><strong><span>Migration Outcomes at Enterprise Scale</span></strong></h2> <p><span>The effects of such a strategy became visible when implemented on a large scale. There was support of over 700 custom tags in more than 6000 files without ever having to rewrite a JSP or tag handler. Migration to Java 17 was done without presentation-layer risk, and the same generator still remains compatible across Java versions. Probably the most crucial argument is that the solution was future-proofed. Since it is based on annotations and scanning of the bytecode, it is not sensitive to most of the changes that have occurred with previous tools.</span></p> <h2><strong><span>Lessons for Enterprise Java Modernization</span></strong></h2> <p><span>The experience provides several general lessons:</span></p> <ul> <li>Tooling gaps can be the real impediments to platform upgrades.</li> <li>Large-scale rewrites are not often acceptable in the enterprise setting.</li> <li>The explicit metadata model is more sustainable than the tooling on the basis of a heuristic.</li> <li>Whereas it is not always safe, build-time solutions can be safer than the runtime adaptations when migrating.</li> </ul> <p><span>To manage such issues, tooling should be treated as a first-class issue and not as something that happens afterwards.</span></p> <h2><strong><span>Looking Ahead</span></strong></h2> <p><span>JSP and tag libraries are not trendy, but they are ingrained in numerous enterprise systems. As Java is still evolving, it will probably become the case that other areas will have similar tooling gaps. The method outlined below, which is annotation-driven, build-time, and backward-compatible, provides a model for addressing such gaps in a pragmatic manner. </span></p> <p><span>Instead of making them rewrite portions that need not be rewritten, teams are able to maintain the steady functionality and conform their tooling to the current platform restrictions. In large, long-serving systems, this equilibrium can lead to successful modernization or to a nonprogressive effort.</span></p></div> </div><p>Opinions expressed by DZone contributors are their own.</p><br><span style='font: #ff0000'>Generated by <a href='https://github.com/andreskrey/readability.php'>Readability.php</a>.</span> Wed, 04 Mar 2026 17:00:00 GMT https://dzone.com/articles/3636263 Sravan Reddy Kathi Comparing Top 3 Java Reporting Tools https://dzone.com/articles/top-3-java-reporting-options <h1>Attention Required! | Cloudflare</h1><div id="cf-wrapper"> <p>Please enable cookies.</p> <div id="cf-error-details"> <p> <h2><span data-translate="unable_to_access">You are unable to access</span> dzone.com</h2> </p> <div> <div> <div> <h2 data-translate="blocked_why_headline">Why have I been blocked?</h2> <p data-translate="blocked_why_detail">This website is using a security service to protect itself from online attacks. The action you just performed triggered the security solution. There are several actions that could trigger this block including submitting a certain word or phrase, a SQL command or malformed data.</p> </div> <div> <h2 data-translate="blocked_resolve_headline">What can I do to resolve this?</h2> <p data-translate="blocked_resolve_detail">You can email the site owner to let them know you were blocked. Please include what you were doing when this page came up and the Cloudflare Ray ID found at the bottom of this page.</p> </div> </div> </div> <p> <span>Cloudflare Ray ID: <strong>9d713c28ac2cd36e</strong></span> <span>•</span> <span id="cf-footer-item-ip"> Your IP: <span id="cf-footer-ip">5.1.64.146</span> <span>•</span> </span> <span><span>Performance &amp; security by</span> <a href="https://www.cloudflare.com/5xx-error-landing" id="brand_link" rel="noopener noreferrer" target="_blank">Cloudflare</a></span> </p> </div> </div><br><span style='font: #ff0000'>Generated by <a href='https://github.com/andreskrey/readability.php'>Readability.php</a>.</span> Tue, 03 Mar 2026 18:00:00 GMT https://dzone.com/articles/3635934 Sergei Iudaev Rethinking Java Web UIs With Jakarta Faces and Quarkus https://dzone.com/articles/why-choose-jakarta-faces-jakarta-ee-ui <h1>Attention Required! | Cloudflare</h1><div id="cf-wrapper"> <p>Please enable cookies.</p> <div id="cf-error-details"> <p> <h2><span data-translate="unable_to_access">You are unable to access</span> dzone.com</h2> </p> <div> <div> <div> <h2 data-translate="blocked_why_headline">Why have I been blocked?</h2> <p data-translate="blocked_why_detail">This website is using a security service to protect itself from online attacks. The action you just performed triggered the security solution. There are several actions that could trigger this block including submitting a certain word or phrase, a SQL command or malformed data.</p> </div> <div> <h2 data-translate="blocked_resolve_headline">What can I do to resolve this?</h2> <p data-translate="blocked_resolve_detail">You can email the site owner to let them know you were blocked. Please include what you were doing when this page came up and the Cloudflare Ray ID found at the bottom of this page.</p> </div> </div> </div> <p> <span>Cloudflare Ray ID: <strong>9d5db9c40a559c0d</strong></span> <span>•</span> <span id="cf-footer-item-ip"> Your IP: <span id="cf-footer-ip">5.1.64.146</span> <span>•</span> </span> <span><span>Performance &amp; security by</span> <a href="https://www.cloudflare.com/5xx-error-landing" id="brand_link" rel="noopener noreferrer" target="_blank">Cloudflare</a></span> </p> </div> </div><br><span style='font: #ff0000'>Generated by <a href='https://github.com/andreskrey/readability.php'>Readability.php</a>.</span> Fri, 27 Feb 2026 18:00:00 GMT https://dzone.com/articles/3636455 Nicolas Duminil A Practical Guide to Building Generative AI in Java https://dzone.com/articles/guide-building-generative-ai-java-genkit <h1>Attention Required! | Cloudflare</h1><div id="cf-wrapper"> <p>Please enable cookies.</p> <div id="cf-error-details"> <p> <h2><span data-translate="unable_to_access">You are unable to access</span> dzone.com</h2> </p> <div> <div> <div> <h2 data-translate="blocked_why_headline">Why have I been blocked?</h2> <p data-translate="blocked_why_detail">This website is using a security service to protect itself from online attacks. The action you just performed triggered the security solution. There are several actions that could trigger this block including submitting a certain word or phrase, a SQL command or malformed data.</p> </div> <div> <h2 data-translate="blocked_resolve_headline">What can I do to resolve this?</h2> <p data-translate="blocked_resolve_detail">You can email the site owner to let them know you were blocked. Please include what you were doing when this page came up and the Cloudflare Ray ID found at the bottom of this page.</p> </div> </div> </div> <p> <span>Cloudflare Ray ID: <strong>9d42db43cbe5d260</strong></span> <span>•</span> <span id="cf-footer-item-ip"> Your IP: <span id="cf-footer-ip">5.1.64.146</span> <span>•</span> </span> <span><span>Performance &amp; security by</span> <a href="https://www.cloudflare.com/5xx-error-landing" id="brand_link" rel="noopener noreferrer" target="_blank">Cloudflare</a></span> </p> </div> </div><br><span style='font: #ff0000'>Generated by <a href='https://github.com/andreskrey/readability.php'>Readability.php</a>.</span> Thu, 26 Feb 2026 16:00:00 GMT https://dzone.com/articles/3637429 Xavier Portilla Edo How to Configure JDK 25 for GitHub Copilot Coding Agent https://dzone.com/articles/how-to-configure-jdk-25-for-github-copilot-coding <h1>Attention Required! | Cloudflare</h1><div id="cf-wrapper"> <p>Please enable cookies.</p> <div id="cf-error-details"> <p> <h2><span data-translate="unable_to_access">You are unable to access</span> dzone.com</h2> </p> <div> <div> <div> <h2 data-translate="blocked_why_headline">Why have I been blocked?</h2> <p data-translate="blocked_why_detail">This website is using a security service to protect itself from online attacks. The action you just performed triggered the security solution. There are several actions that could trigger this block including submitting a certain word or phrase, a SQL command or malformed data.</p> </div> <div> <h2 data-translate="blocked_resolve_headline">What can I do to resolve this?</h2> <p data-translate="blocked_resolve_detail">You can email the site owner to let them know you were blocked. Please include what you were doing when this page came up and the Cloudflare Ray ID found at the bottom of this page.</p> </div> </div> </div> <p> <span>Cloudflare Ray ID: <strong>9d42db45cacf9b9a</strong></span> <span>•</span> <span id="cf-footer-item-ip"> Your IP: <span id="cf-footer-ip">5.1.64.146</span> <span>•</span> </span> <span><span>Performance &amp; security by</span> <a href="https://www.cloudflare.com/5xx-error-landing" id="brand_link" rel="noopener noreferrer" target="_blank">Cloudflare</a></span> </p> </div> </div><br><span style='font: #ff0000'>Generated by <a href='https://github.com/andreskrey/readability.php'>Readability.php</a>.</span> Wed, 25 Feb 2026 13:00:00 GMT https://dzone.com/articles/3636292 Bruno Borges Data Driven API Testing in Java with Rest-Assured and TestNG: Part 1 https://dzone.com/articles/data-driven-api-testing-in-java-with-rest-assured <h1>Attention Required! | Cloudflare</h1><div id="cf-wrapper"> <p>Please enable cookies.</p> <div id="cf-error-details"> <p> <h2><span data-translate="unable_to_access">You are unable to access</span> dzone.com</h2> </p> <div> <div> <div> <h2 data-translate="blocked_why_headline">Why have I been blocked?</h2> <p data-translate="blocked_why_detail">This website is using a security service to protect itself from online attacks. The action you just performed triggered the security solution. There are several actions that could trigger this block including submitting a certain word or phrase, a SQL command or malformed data.</p> </div> <div> <h2 data-translate="blocked_resolve_headline">What can I do to resolve this?</h2> <p data-translate="blocked_resolve_detail">You can email the site owner to let them know you were blocked. Please include what you were doing when this page came up and the Cloudflare Ray ID found at the bottom of this page.</p> </div> </div> </div> <p> <span>Cloudflare Ray ID: <strong>9d2ea4fdc86cd22a</strong></span> <span>•</span> <span id="cf-footer-item-ip"> Your IP: <span id="cf-footer-ip">5.1.64.146</span> <span>•</span> </span> <span><span>Performance &amp; security by</span> <a href="https://www.cloudflare.com/5xx-error-landing" id="brand_link" rel="noopener noreferrer" target="_blank">Cloudflare</a></span> </p> </div> </div><br><span style='font: #ff0000'>Generated by <a href='https://github.com/andreskrey/readability.php'>Readability.php</a>.</span> Mon, 23 Feb 2026 18:00:00 GMT https://dzone.com/articles/3636354 Faisal Khatri Building a Sentiment Analysis Pipeline With Apache Camel and Deep Java Library (DJL) https://dzone.com/articles/apache-camel-djl-sentiment-analysis-java <img src="https://dz2cdn1.dzone.com/storage/article-thumb/18889275-thumb.jpg" /><h1>Build a Sentiment Analysis Pipeline With Apache Camel & DJL</h1><div> <div><p>Sentiment analysis is now a key part of many applications. Whether you’re processing customer feedback, sorting support tickets, or tracking social media, knowing how users feel can be just as important as knowing what they say.</p> <p>For Java developers, the main challenge isn’t finding machine learning models, but applying them within the existing or new Java applications without relying on Python. Most NLP models are shown in Python notebooks, while real systems use file pipelines, routing, retries, fallbacks, and monitoring. Many teams find it hard to connect these pieces smoothly.</p> <p>This tutorial will show you how to build a sentiment analysis pipeline in pure Java with Apache Camel and the <a href="https://dzone.com/articles/deep-learning-with-spring-boot-and-djl">Deep Java Library</a> (DJL). We will cover handling text files, running sentiment checks with a ready-to-go DistilBERT model, tidying up the outputs, and gracefully handling glitches, all while leaning on those trusty Enterprise Integration Patterns you are probably already familiar with.</p> <h2><strong>What You'll Learn</strong></h2> <p>By the time you're done here, you'll be comfortable with:</p> <ul> <li>Develop a file-based NLP pipeline using Apache Camel.</li> <li>Use a pre-trained sentiment analysis model via Camel’s DJL component.</li> <li>Understand the djl: URI syntax and model configuration in Apache Camel.</li> <li>Structure routes with fallback handling and clean output formatting.</li> <li>Run sentiment analysis locally using the Java and Apache Camel frameworks, without external APIs or Python services.</li> </ul> <h2><strong>Frameworks Used<br></br></strong></h2> <h3><strong>Apache Camel</strong></h3> <p><a href="https://dzone.com/articles/apache-camel-spring-boot-robust-integration-solutions">Apache Camel</a> is an awesome open-source integration framework built on Enterprise Integration Patterns. It has great components for connecting systems, moving data, and orchestrating workflows using declarative routes.</p> <p>In this example, we look at file ingestion, Message transformation, routing, conditional logic, error handling, and output persistence.</p> <h3><strong>Deep Java Library (DJL)</strong></h3> <p>DJL is a deep learning framework for Java that is engine-agnostic. It strikes a nice balance between quick performance and solid accuracy, making it perfect for sentiment tasks without bogging things down.</p> <p>We use the Camel-DJL component to download and cache a pre-trained DistilBERT model, run sentiment inference inside the <a href="https://dzone.com/articles/jvm-architecture-explained">JVM</a>, and return structured classification results.</p> <h3><strong>DistilBERT for Sentiment Analysis</strong></h3> <p>DistilBERT is a smaller, fast transformer model based on BERT. It gives a good mix of speed and accuracy for sentiment analysis tasks.</p> <h2><strong>Project Structure</strong></h2> <p>Let's look at the project structure below:</p> <div contenteditable="false"> <div contenteditable="false"> <div data-code="camel-sentiment-analysis/&#xA;├── src/main/java/com/example/sentimentanalysis/&#xA;│ ├── MainApp.java # Application entry point&#xA;│ ├── routes/&#xA;│ │ └── SentimentAnalysisRoutes.java # Camel route for text processing&#xA;│ └── processor/&#xA;│ ├── ClassificationsFormatter.java # Formats sentiment results&#xA;│ └── FallbackFormatter.java # Handles unexpected outputs&#xA;├── src/main/resources/&#xA;│ └── application.properties # Camel configuration&#xA;├── data/&#xA;│ ├── input/ # Input text files&#xA;│ │ ├── sample-positive.txt # Sample positive text&#xA;│ │ └── sample-negative.txt # Sample negative text&#xA;│ ├── output/ # Sentiment analysis results&#xA;│ └── analyzed/ # Processed files archive&#xA;├── gradle/wrapper/ # Gradle wrapper files&#xA;├── build.gradle # Project dependencies&#xA;├── settings.gradle # Gradle settings&#xA;├── gradlew.bat # Gradle wrapper script&#xA;├── README.md # Main documentation" data-lang="text/x-rst"> <pre><code lang="text/x-rst">camel-sentiment-analysis/ ├── src/main/java/com/example/sentimentanalysis/ │ ├── MainApp.java # Application entry point │ ├── routes/ │ │ └── SentimentAnalysisRoutes.java # Camel route for text processing │ └── processor/ │ ├── ClassificationsFormatter.java # Formats sentiment results │ └── FallbackFormatter.java # Handles unexpected outputs ├── src/main/resources/ │ └── application.properties # Camel configuration ├── data/ │ ├── input/ # Input text files │ │ ├── sample-positive.txt # Sample positive text │ │ └── sample-negative.txt # Sample negative text │ ├── output/ # Sentiment analysis results │ └── analyzed/ # Processed files archive ├── gradle/wrapper/ # Gradle wrapper files ├── build.gradle # Project dependencies ├── settings.gradle # Gradle settings ├── gradlew.bat # Gradle wrapper script ├── README.md # Main documentation</code></pre> </div> </div> </div> <h3>Gradle Dependencies</h3> <p>build.gradle</p> <div contenteditable="false"> <div contenteditable="false"> <div data-code="plugins {&#xA;&#x9;id 'java'&#xA;&#x9;id 'application'&#xA;}&#xA;&#xA;group = 'com.example'&#xA;version = '1.0.0'&#xA;description = 'Sentiment Analysis with Apache Camel and DJL'&#xA;&#xA;java {&#xA;&#x9;toolchain {&#xA;&#x9;&#x9;languageVersion = JavaLanguageVersion.of(21)&#xA;&#x9;}&#xA;}&#xA;&#xA;application {&#xA;&#x9;mainClass = 'com.example.sentimentanalysis.MainApp'&#xA;}&#xA;&#xA;repositories {&#xA;&#x9;mavenCentral()&#xA;}&#xA;&#xA;dependencies {&#xA;&#x9;// Apache Camel&#xA;&#x9;implementation 'org.apache.camel:camel-core:4.17.0'&#xA;&#x9;implementation 'org.apache.camel:camel-main:4.17.0'&#xA;&#x9;implementation 'org.apache.camel:camel-file:4.17.0'&#xA;&#x9;implementation 'org.apache.camel:camel-djl:4.17.0'&#xA;&#x9;&#xA;&#x9;// DJL (Deep Java Library) for sentiment analysis&#xA;&#x9;implementation platform('ai.djl:bom:0.36.0')&#xA;&#x9;implementation 'ai.djl:api'&#xA;&#x9;&#xA;&#x9;// PyTorch engine for DistilBERT sentiment analysis&#xA;&#x9;implementation 'ai.djl.pytorch:pytorch-engine'&#xA;&#x9;implementation 'ai.djl.pytorch:pytorch-model-zoo'&#xA;&#x9;&#xA;&#x9;// Use CPU-only PyTorch runtime for Windows&#xA;&#x9;runtimeOnly 'ai.djl.pytorch:pytorch-native-cpu:2.1.1:win-x86_64'&#xA;&#x9;&#xA;&#x9;// Logging&#xA;&#x9;implementation 'org.slf4j:slf4j-simple:2.0.16'&#xA;}&#xA;" data-lang="text/x-groovy"> <pre><code lang="text/x-groovy">plugins { id 'java' id 'application' } group = 'com.example' version = '1.0.0' description = 'Sentiment Analysis with Apache Camel and DJL' java { toolchain { languageVersion = JavaLanguageVersion.of(21) } } application { mainClass = 'com.example.sentimentanalysis.MainApp' } repositories { mavenCentral() } dependencies { // Apache Camel implementation 'org.apache.camel:camel-core:4.17.0' implementation 'org.apache.camel:camel-main:4.17.0' implementation 'org.apache.camel:camel-file:4.17.0' implementation 'org.apache.camel:camel-djl:4.17.0' // DJL (Deep Java Library) for sentiment analysis implementation platform('ai.djl:bom:0.36.0') implementation 'ai.djl:api' // PyTorch engine for DistilBERT sentiment analysis implementation 'ai.djl.pytorch:pytorch-engine' implementation 'ai.djl.pytorch:pytorch-model-zoo' // Use CPU-only PyTorch runtime for Windows runtimeOnly 'ai.djl.pytorch:pytorch-native-cpu:2.1.1:win-x86_64' // Logging implementation 'org.slf4j:slf4j-simple:2.0.16' } </code></pre> </div> </div> </div> <p>The DJL BOM make sures the versions are consistent across engines and models.</p> <h3>Application Entry Point</h3> <p>The application starts up using the <code>MainApp</code> class and starts Camel using <code>Main</code>:</p> <div contenteditable="false"> <div contenteditable="false"> <div data-code="package com.example.sentimentanalysis;&#xA;&#xA;import com.example.sentimentanalysis.routes.SentimentAnalysisRoutes;&#xA;import org.apache.camel.main.Main;&#xA;&#xA;public class MainApp {&#xA;&#xA; public static void main(String[] args) throws Exception {&#xA; &#xA; // Create and configure Camel Main&#xA; Main main = new Main();&#xA;&#xA; // Add routes&#xA; main.configure().addRoutesBuilder(new SentimentAnalysisRoutes());&#xA;&#xA; main.run();&#xA; }&#xA;}&#xA;" data-lang="text/x-java"> <pre><code lang="text/x-java">package com.example.sentimentanalysis; import com.example.sentimentanalysis.routes.SentimentAnalysisRoutes; import org.apache.camel.main.Main; public class MainApp { public static void main(String[] args) throws Exception { // Create and configure Camel Main Main main = new Main(); // Add routes main.configure().addRoutesBuilder(new SentimentAnalysisRoutes()); main.run(); } } </code></pre> </div> </div> </div> <h3>Sentiment Analysis Route</h3> <p>The SentimentAnalysisRoutes.java is where the core logic is implemented using camel-djl component's URI. It uses the "from" component for file ingestion (Watches for a file, processes them one at a time to extract the text, archives them with a timestamp), and uses a single "to" URI endpoint to run sentiment analysis using the DJL component URI with a lazy producer, which allows the route to start even if the endpoint can't connect. The producer starts on the first message, enabling error handling during routing.</p> <p>SentimentAnalysisRoutes.java</p> <div contenteditable="false"> <div contenteditable="false"> <div data-code="package com.example.sentimentanalysis.routes;&#xA;&#xA;import com.example.sentimentanalysis.processor.ClassificationsFormatter;&#xA;import com.example.sentimentanalysis.processor.FallbackFormatter;&#xA;import org.apache.camel.builder.RouteBuilder;&#xA;&#xA;import java.io.File;&#xA;import java.nio.file.Files;&#xA;&#xA;/**&#xA; * Apache Camel routes for sentiment analysis.&#xA; * Processes text files from input folder, runs sentiment analysis using DJL,&#xA; * and writes results to output folder.&#xA; */&#xA;public class SentimentAnalysisRoutes extends RouteBuilder {&#xA;&#xA; @Override&#xA; public void configure() throws Exception {&#xA;&#xA; // Route to process text files from input folder&#xA; from(&quot;file:data/input?include=.*\\.txt&amp;noop=false&amp;move=../analyzed/${date:now:yyyyMMdd-HHmmss}-${file:name}&quot;)&#xA; .routeId(&quot;sentiment-analysis-route&quot;)&#xA; .log(&quot;Processing text file: ${file:name}&quot;)&#xA;&#xA; // Read file content as String&#xA; .process(exchange -> {&#xA; File textFile = exchange.getIn().getBody(File.class);&#xA; String content = Files.readString(textFile.toPath());&#xA; exchange.getIn().setBody(content);&#xA; })&#xA;&#xA; .to(&quot;djl:nlp/sentiment_analysis?artifactId=ai.djl.pytorch:distilbert:0.0.1&amp;lazyStartProducer=true&quot;)&#xA;&#xA; // Convert output to a text report using Camel choice/bean components&#xA; .choice()&#xA; .when(body().isInstanceOf(ai.djl.modality.Classifications.class))&#xA; .bean(new ClassificationsFormatter(), &quot;format&quot;)&#xA; .otherwise()&#xA; .bean(new FallbackFormatter(), &quot;format&quot;)&#xA; .end()&#xA;&#xA; .log(&quot;Sentiment analysis done for ${file:name}&quot;)&#xA;&#xA; // Write results to output folder&#xA; .to(&quot;file:data/output?fileName=${date:now:yyyyMMdd-HHmmss}-${file:name.noext}-sentiment.txt&quot;)&#xA; .log(&quot;Results saved to output folder&quot;);&#xA; }&#xA;}&#xA;" data-lang="text/x-java"> <pre><code lang="text/x-java">package com.example.sentimentanalysis.routes; import com.example.sentimentanalysis.processor.ClassificationsFormatter; import com.example.sentimentanalysis.processor.FallbackFormatter; import org.apache.camel.builder.RouteBuilder; import java.io.File; import java.nio.file.Files; /** * Apache Camel routes for sentiment analysis. * Processes text files from input folder, runs sentiment analysis using DJL, * and writes results to output folder. */ public class SentimentAnalysisRoutes extends RouteBuilder { @Override public void configure() throws Exception { // Route to process text files from input folder from("file:data/input?include=.*\\.txt&amp;noop=false&amp;move=../analyzed/${date:now:yyyyMMdd-HHmmss}-${file:name}") .routeId("sentiment-analysis-route") .log("Processing text file: ${file:name}") // Read file content as String .process(exchange -&gt; { File textFile = exchange.getIn().getBody(File.class); String content = Files.readString(textFile.toPath()); exchange.getIn().setBody(content); }) .to("djl:nlp/sentiment_analysis?artifactId=ai.djl.pytorch:distilbert:0.0.1&amp;lazyStartProducer=true") // Convert output to a text report using Camel choice/bean components .choice() .when(body().isInstanceOf(ai.djl.modality.Classifications.class)) .bean(new ClassificationsFormatter(), "format") .otherwise() .bean(new FallbackFormatter(), "format") .end() .log("Sentiment analysis done for ${file:name}") // Write results to output folder .to("file:data/output?fileName=${date:now:yyyyMMdd-HHmmss}-${file:name.noext}-sentiment.txt") .log("Results saved to output folder"); } } </code></pre> </div> </div> </div> <p>Let’s break this down:</p> <div contenteditable="false"> <div contenteditable="false"> <div data-code=".to(&quot;djl:nlp/sentiment_analysis?artifactId=ai.djl.pytorch:distilbert:0.0.1&amp;lazyStartProducer=true&quot;)" data-lang="text/x-java"> <pre><code lang="text/x-java">.to("djl:nlp/sentiment_analysis?artifactId=ai.djl.pytorch:distilbert:0.0.1&amp;lazyStartProducer=true")</code></pre> </div> </div> </div> <ul type="disc"> <li><strong><strong>djl</strong> </strong>– Camel DJL component</li> <li><strong><strong>nlp/sentiment_analysis</strong> </strong>– NLP task type</li> <li><strong><strong>artifactId</strong> </strong>– Identifies the model from DJL’s Model Zoo</li> <li><strong><strong>lazyStartProducer=true</strong> </strong>– Defers model loading until first use</li> </ul> <p>This single line replaces hundreds of lines of traditional ML plumbing.</p> <h2>How to Run the Application</h2> <p>Build and run using Gradle:</p> <p>Then drop text files into data/input/, for example:</p> <div contenteditable="false"> <div contenteditable="false"> <div data-code="This is an amazing product! I absolutely love it and would highly recommend it." data-lang="text/plain"> <pre><code lang="text/plain">This is an amazing product! I absolutely love it and would highly recommend it.</code></pre> </div> </div> </div> <p>The analyzed sentiment is written to data/output/, and the original file is archived.</p> <p>ClassificationsFormatter.java</p> <div contenteditable="false"> <div contenteditable="false"> <div data-code="package com.example.sentimentanalysis.processor;&#xA;&#xA;import ai.djl.modality.Classifications;&#xA;import org.apache.camel.Exchange;&#xA;&#xA;import java.util.List;&#xA;&#xA;/**&#xA; * Bean to format DJL Classifications object into a text report for sentiment&#xA; * analysis.&#xA; */&#xA;public class ClassificationsFormatter {&#xA;&#xA;&#x9;public String format(Classifications classifications, Exchange exchange) {&#xA;&#x9;&#x9;StringBuilder sb = new StringBuilder();&#xA;&#x9;&#x9;String fileName = exchange.getIn().getHeader(&quot;CamelFileName&quot;, String.class);&#xA;&#xA;&#x9;&#x9;sb.append(&quot;Text File: &quot;).append(fileName).append('\n');&#xA;&#x9;&#x9;sb.append(&quot;Sentiment Analysis Results\n&quot;);&#xA;&#x9;&#x9;sb.append(&quot;==========================\n\n&quot;);&#xA;&#xA;&#x9;&#x9;List&lt;Classifications.Classification> allResults = classifications.topK();&#xA;&#xA;&#x9;&#x9;if (!allResults.isEmpty()) {&#xA;&#x9;&#x9;&#x9;Classifications.Classification top = allResults.get(0);&#xA;&#x9;&#x9;&#x9;sb.append(&quot;Overall Sentiment: &quot;).append(top.getClassName().toUpperCase()).append(&quot; (Confidence: &quot;)&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;.append(String.format(&quot;%.2f%%&quot;, top.getProbability() * 100)).append(&quot;)\n\n&quot;);&#xA;&#x9;&#x9;}&#xA;&#xA;&#x9;&#x9;sb.append(&quot;Sentiment Breakdown:\n&quot;);&#xA;&#x9;&#x9;for (int i = 0; i &lt; allResults.size(); i++) {&#xA;&#x9;&#x9;&#x9;Classifications.Classification c = allResults.get(i);&#xA;&#x9;&#x9;&#x9;sb.append(String.format(&quot; %s: %.2f%%\n&quot;, c.getClassName(), c.getProbability() * 100));&#xA;&#x9;&#x9;}&#xA;&#xA;&#x9;&#x9;return sb.toString();&#xA;&#x9;}&#xA;}&#xA;" data-lang="text/x-java"> <pre><code lang="text/x-java">package com.example.sentimentanalysis.processor; import ai.djl.modality.Classifications; import org.apache.camel.Exchange; import java.util.List; /** * Bean to format DJL Classifications object into a text report for sentiment * analysis. */ public class ClassificationsFormatter { public String format(Classifications classifications, Exchange exchange) { StringBuilder sb = new StringBuilder(); String fileName = exchange.getIn().getHeader("CamelFileName", String.class); sb.append("Text File: ").append(fileName).append('\n'); sb.append("Sentiment Analysis Results\n"); sb.append("==========================\n\n"); List&lt;Classifications.Classification&gt; allResults = classifications.topK(); if (!allResults.isEmpty()) { Classifications.Classification top = allResults.get(0); sb.append("Overall Sentiment: ").append(top.getClassName().toUpperCase()).append(" (Confidence: ") .append(String.format("%.2f%%", top.getProbability() * 100)).append(")\n\n"); } sb.append("Sentiment Breakdown:\n"); for (int i = 0; i &lt; allResults.size(); i++) { Classifications.Classification c = allResults.get(i); sb.append(String.format(" %s: %.2f%%\n", c.getClassName(), c.getProbability() * 100)); } return sb.toString(); } } </code></pre> </div> </div> </div> <p>On a successful classification, ClassificationsFormatter converts DJL’s output into a clean, human-readable report like below:</p> <div contenteditable="false"> <div contenteditable="false"> <div data-code="Text File: sample-positive.txt&#xA;Sentiment Analysis Results&#xA;==========================&#xA;&#xA;Overall Sentiment: POSITIVE (Confidence: 99.98%)&#xA;&#xA;Sentiment Breakdown:&#xA; Positive: 99.98%&#xA; Negative: 0.02%&#xA;" data-lang="text/plain"> <pre><code lang="text/plain">Text File: sample-positive.txt Sentiment Analysis Results ========================== Overall Sentiment: POSITIVE (Confidence: 99.98%) Sentiment Breakdown: Positive: 99.98% Negative: 0.02% </code></pre> </div> </div> </div> <p>In case of an ML failure, there is a FallbackFormatter that ensures the pipeline continues to produce meaningful output rather than crashing, which follows a critical production pattern to fail softly.</p> <p>FallbackFormatter.java</p> <div contenteditable="false"> <div contenteditable="false"> <div data-code="package com.example.sentimentanalysis.processor;&#xA;&#xA;import org.apache.camel.Exchange;&#xA;&#xA;/**&#xA; * Bean to format unexpected result types into a text report.&#xA; */&#xA;public class FallbackFormatter {&#xA;&#xA;&#x9;public String format(Object result, Exchange exchange) {&#xA;&#x9;&#x9;StringBuilder sb = new StringBuilder();&#xA;&#x9;&#x9;String fileName = exchange.getIn().getHeader(&quot;CamelFileName&quot;, String.class);&#xA;&#xA;&#x9;&#x9;sb.append(&quot;Text File: &quot;).append(fileName).append('\n');&#xA;&#x9;&#x9;sb.append(&quot;Raw result type: &quot;).append(result == null ? &quot;null&quot; : result.getClass().getName()).append('\n');&#xA;&#x9;&#x9;sb.append(&quot;Result:\n&quot;).append(String.valueOf(result)).append('\n');&#xA;&#xA;&#x9;&#x9;return sb.toString();&#xA;&#x9;}&#xA;}&#xA;" data-lang="text/x-java"> <pre><code lang="text/x-java">package com.example.sentimentanalysis.processor; import org.apache.camel.Exchange; /** * Bean to format unexpected result types into a text report. */ public class FallbackFormatter { public String format(Object result, Exchange exchange) { StringBuilder sb = new StringBuilder(); String fileName = exchange.getIn().getHeader("CamelFileName", String.class); sb.append("Text File: ").append(fileName).append('\n'); sb.append("Raw result type: ").append(result == null ? "null" : result.getClass().getName()).append('\n'); sb.append("Result:\n").append(String.valueOf(result)).append('\n'); return sb.toString(); } } </code></pre> </div> </div> </div> <h3>DJL Behind the Scenes</h3> <p>On first execution, the DistilBERT model is downloaded automatically, &amp; Native PyTorch libraries are initialized. The model is cached locally, and on subsequent runs it loads from cache, resulting in significantly faster startup.</p> <h3>Production Considerations</h3> <p>For performance reasons, always warm up the model on startup if latency is a concern and allocate sufficient JVM heap (models are memory-intensive).</p> <p>Scale horizontally with multiple Camel instances or vertically using GPU-enabled DJL engines. Always use lazyStartProducer for ML endpoints.</p> <h2><strong>Conclusion</strong></h2> <p>This tutorial demonstrates that <strong>machine learning does not need to be a separate system</strong>. With Apache Camel and DJL, sentiment analysis becomes just another step in your integration flow, composable, observable, and production-ready. Compared to external ML APIs, there is no per-request cost, data is not going out, and there is full control over routing and error handling.</p> <p>Compared to Python pipelines, it is native integration with enterprise Java systems &amp; first class support for integration patterns.</p> <p>If you already use Camel, adding NLP capabilities is no longer a leap. It is a small, well-structured step.</p></div> </div><p>Opinions expressed by DZone contributors are their own.</p><br><span style='font: #ff0000'>Generated by <a href='https://github.com/andreskrey/readability.php'>Readability.php</a>.</span> Mon, 23 Feb 2026 13:00:00 GMT https://dzone.com/articles/3632529 Vignesh Durai