{"id":33945,"date":"2024-02-29T12:51:19","date_gmt":"2024-02-29T17:51:19","guid":{"rendered":"https:\/\/www.eginnovations.com\/blog\/?p=33945"},"modified":"2024-02-29T12:51:19","modified_gmt":"2024-02-29T17:51:19","slug":"demystifying-java-lambda-expressions","status":"publish","type":"post","link":"https:\/\/www.eginnovations.com\/blog\/demystifying-java-lambda-expressions\/","title":{"rendered":"Demystifying Java Lambda Expressions"},"content":{"rendered":"<div class=\"inner_content\">\n<div style=\"padding: 20px 20px 0; border: 1px solid #ffd392; background: #fcf8ef; margin-bottom: 30px;\">\n<h2><span class=\"ez-toc-section\" id=\"SUMMARY\"><\/span>SUMMARY<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>SRE and IT Operations play a critical role in ensuring reliable, high-performance applications. Yet, SREs (Site Reliability Engineers) often face &#8216;thrown-over-the-wall&#8217; code deployments to operate without having insights into the code-level features.<\/p>\n<p>In my <a href=\"https:\/\/www.eginnovations.com\/blog\/is-your-java-observability-tool-lambda-expressions-aware\/\/\"> previous article<\/a> (\u201cIs your Java Observability tool Lambda Expressions aware?&#8221;), I delved into one such code-level feature: Java lambda expressions which replace anonymous inner classes. The latter can negatively impact your Java application&#8217;s performance.<\/p>\n<p>The choice of lambda vs anonymous classes is not just some intricate code-level design feature. It has a direct bearing on application performance and can impact Service Level Indicators (SLIs) negatively, which is what SREs are jointly responsible for.<\/p>\n<p>How do SREs know that there are better code-level alternatives? SREs need an X-Ray into code so they can swim upstream and influence code-level design decisions. APM and observability tools can provide this visibility.<\/p>\n<p>My article struck a chord with many SREs, prompting numerous questions seeking more details on Java lambda expressions.<\/p>\n<p>A few questions that I\u2019ll answer today, after a brief recap:<\/p>\n<ul>\n<li>What is a Java Lambda Expression and what are their benefits?<\/li>\n<li>Will you improve performance if you use Lambda Expressions (rather than anonymous classes)?<\/li>\n<li>Why are some APM tools blind to Java Lambda Expressions? (hint: they are hard to instrument for tracing and monitoring)<\/li>\n<li>Takeaway for SREs: Swim upstream, shift-left and influence AppDev<\/li>\n<\/ul>\n<\/div>\n<h2><span class=\"ez-toc-section\" id=\"What_is_a_Java_lambda_expression\"><\/span>What is a Java lambda expression?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Java lambda expressions provide a concise way to encapsulate business logic. You can represent an anonymous block of code that can either be an expression or a series of statements, ultimately returning a result. The structure of a lambda expression is as follows:<\/p>\n<pre><code class=\"language-java\">(argument list) -&gt; { body }<\/code><\/pre>\n<p>The syntax includes an argument list, an arrow token (-&gt;), and a body. I\u2019ll walk you through some code examples in the next section which will make this clear.<\/p>\n<p>This construct enables the creation of anonymous functions or methods without explicitly declared names. You can succinctly define behavior that can be passed as arguments to methods, similar to the concept of anonymous classes. Lambda expressions facilitate the expression of code in a compact and expressive manner, enhancing the readability and flexibility of Java code.<\/p>\n<div style=\"padding: 20px 20px 0; border: 1px solid #ffd392; background: #fcf8ef; margin-bottom: 30px;\">\n<p>The term &#8220;lambda&#8221; is derived from lambda calculus which symbolizes function abstraction.Lambda expressions were introduced in Java 8 in the year 2014. They allow for a more functional programming style enabling streamlined and expressive code.<\/p>\n<\/div>\n<h2><span class=\"ez-toc-section\" id=\"Java_lambda_illustrated_with_examples\"><\/span>Java lambda illustrated with examples<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Let\u2019s look at some sample code to get more familiar with lambda expressions.<\/p>\n<p><strong>Task:<\/strong> Calculate Interest for a Loan<\/p>\n<p>InterestCalculator loanInterestCalculator = (principal, rate, time) -&gt; principal * rate * time \/ 100;<\/p>\n<p><strong>Task:<\/strong> Apply Discount to an Online Order<\/p>\n<p>OrderDiscountProcessor discountProcessor = (totalAmount) -&gt; totalAmount &#8211; (totalAmount * 0.1);<\/p>\n<p>What you are seeing in the above examples is the following:<\/p>\n<ul>\n<li><strong>They are anonymous: <\/strong>They don\u2019t have an explicit name like a method would normally have. That\u2019s good &#8211; less code to write and debug.<\/li>\n<li><strong>They are functions: <\/strong>A lambda isn\u2019t associated with a particular class (unlike a method is). But like a method, a lambda has a list of parameters, a body, a return type, and a possible list of exceptions that can be thrown.<\/li>\n<li><strong>Passed around<\/strong>\u2014A lambda expression can be passed as argument to a method or stored in a variable.<\/li>\n<li><strong>Concise<\/strong>\u2014You don\u2019t need to write a lot of boilerplate like you do for Java anonymous classes.<\/li>\n<\/ul>\n<p><b>You might come across the expression &#8220;passing code\u201d. What does that mean?<\/b><\/p>\n<p>When we talk about &#8220;passing code,&#8221; we are typically referring to the ability to provide a block of executable code (a function or behavior) as an argument to another piece of code. This is often used in the context of passing behavior to a method or function.<\/p>\n<p><b>Why should you care about lambda expressions?<\/b><\/p>\n<p>Before Java lambda expressions were introduced, passing code using anonymous classes was tedious and verbose. Lambdas fix this problem &#8211; you can pass code in a concise way.<\/p>\n<div style=\"font-size: 1.5em; border-top: 2px solid #ffd392; border-bottom: 2px solid #ffd392; line-height: 1.5em; padding: 10px 0; margin-bottom: 30px;\"><em>Lambda expressions promote functional programming design patterns. You no longer need to write clumsy code using anonymous classes to benefit from behavior parameterization.<\/em><\/div>\n<p><a href=\"https:\/\/www.eginnovations.com\/blog\/wp-content\/uploads\/2024\/02\/chart-1-view.jpg\" data-rel=\"lightbox-image-0\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-34017\" src=\"https:\/\/www.eginnovations.com\/blog\/wp-content\/uploads\/2024\/02\/chart-1-.webp\" alt=\"\" width=\"850\" height=\"228\" \/><\/a><\/p>\n<h2><span class=\"ez-toc-section\" id=\"An_alternative_to_anonymous_classes\"><\/span>An alternative to anonymous classes<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Let\u2019s first talk about anonymous classes.<\/p>\n<p>In Java, you can create classes that don\u2019t have a name. These are just like local classes (classes defined in a block) that you may already be familiar with. However, the key difference is that anonymous classes don&#8217;t have a name.<\/p>\n<p>Anonymous classes enable you to declare and instantiate a class simultaneously, providing a way to create ad hoc implementations on the fly. This approach simplifies the code by combining class declaration and instantiation in a single step, making it convenient for scenarios where a temporary, unnamed class is needed.<\/p>\n<p>The <a href=\"https:\/\/docs.oracle.com\/javase\/tutorial\/java\/javaOO\/lambdaexpressions.html\" target=\"_blank\" rel=\"nofollow noindex noopener\">Oracle documentation<\/a> makes it very clear:<\/p>\n<p><em>Anonymous Classes, shows you how to implement a base class without giving it a name. Although this is often more concise than a named class, for classes with only one method, even an anonymous class seems a bit excessive and cumbersome. <strong>Lambda expressions let you express instances of single-method classes more compactly<\/strong>.<\/em><\/p>\n<p>Later in this article, we\u2019ll go through the specific benefits of Java lambda expressions. For now, here\u2019s a list of things to keep in mind on \u201cwhy Java lambdas\u201d:<\/p>\n<ul>\n<li>Java lambdas are a replacement for anonymous classes. You don\u2019t need to explicitly declare a method, as seen in traditional anonymous classes.<\/li>\n<li>They are shortcuts for writing short, simple methods. Java lambdas are great at making your code shorter and easier to understand.<\/li>\n<li>They work especially well with a programming style called functional programming, where you can do some cool things like passing functions as if they were regular data.<\/li>\n<li>Java lambdas seamlessly integrate with Java streams, enabling concise and expressive data processing. Stream pipelines can operate sequentially or in parallel. Lambdas allow for efficient parallel processing of collections, harnessing the full potential of multicore CPUs. This combination enhances performance by distributing computations, making Java development more scalable and responsive.<\/li>\n<\/ul>\n<h2><span class=\"ez-toc-section\" id=\"Anonymous_classes_also_have_a_bunch_of_performance_disadvantages\"><\/span>Anonymous classes also have a bunch of performance disadvantages<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Anonymous classes also come with undesirable characteristics that can impact your application&#8217;s performance.<\/p>\n<ul>\n<li>Anonymous classes can prolong JVM start-up times due to the additional bytecode generation and class loading complexities they introduce.<\/li>\n<li>Increased JAR file size bloat due to generation of many class files. This hinders deployment efficiency and increases JAR download times.<\/li>\n<li>Anonymous classes can waste precious metaspace in the JVM, impacting memory usage and potentially leading to performance issues.<\/li>\n<li>Anonymous classes are also code cache inefficient, as their dynamic nature can result in less effective utilization of the code cache, negatively affecting runtime performance. Anonymous classes impact JVM start-up times<\/li>\n<\/ul>\n<p><a href=\"https:\/\/www.eginnovations.com\/supported-technologies\/java-application-monitoring\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-33977\" src=\"https:\/\/www.eginnovations.com\/blog\/wp-content\/uploads\/2024\/02\/banner.jpg\" alt=\"\" width=\"850\" height=\"180\" srcset=\"https:\/\/www.eginnovations.com\/blog\/wp-content\/uploads\/2024\/02\/banner.jpg 850w, https:\/\/www.eginnovations.com\/blog\/wp-content\/uploads\/2024\/02\/banner-300x64.jpg 300w, https:\/\/www.eginnovations.com\/blog\/wp-content\/uploads\/2024\/02\/banner-768x163.jpg 768w, https:\/\/www.eginnovations.com\/blog\/wp-content\/uploads\/2024\/02\/banner-800x169.jpg 800w, https:\/\/www.eginnovations.com\/blog\/wp-content\/uploads\/2024\/02\/banner-310x66.jpg 310w, https:\/\/www.eginnovations.com\/blog\/wp-content\/uploads\/2024\/02\/banner-140x30.jpg 140w\" sizes=\"auto, (max-width: 850px) 100vw, 850px\" \/><\/a><\/p>\n<p>Lambda expressions solve many of the above performance benefits, which we\u2019ll see below.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Benefits_of_Lambda_Expressions_illustrated_with_code_examples\"><\/span>Benefits of Lambda Expressions illustrated with code examples<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<h3><span class=\"ez-toc-section\" id=\"Benefit_1_Concise_and_better_clarity_%3E_more_developer_productivity\"><\/span>Benefit #1: Concise and better clarity =&gt; more developer productivity<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Let\u2019s understand with an example. You are writing an e-commerce application that needs to calculate the total price of products exceeding $200. You can do it the old way or the modern way.<\/p>\n<table>\n<tbody>\n<tr>\n<td width=\"50%\"><strong>Verbose traditional code using Anonymous classes<\/strong><\/td>\n<td width=\"50%\"><strong>Concise and modern equivalent using Java lambda expressions<\/strong><\/td>\n<\/tr>\n<tr>\n<td>\n<pre><code class=\"language-java\">double totalPrice = 0.0;\n\nfor (Product product : products) {\n\nif (new PriceChecker() {\n\n@Override\n\npublic boolean test(Product product) {\n\nreturn product.getPrice() &gt; 200.0;\n\n}\n\n}.test(product)) {\n\ntotalPrice += new PriceExtractor() {\n\n@Override\n\npublic double apply(Product product) {\n\nreturn product.getPrice();\n\n}\n\n}.apply(product);\n\n}\n\n}<\/code><\/pre>\n<p>\/\/ Helper interfaces<strong> (anonymous classes)<\/strong><\/p>\n<pre><code class=\"language-java\">interface PriceChecker {\n\nboolean test(Product product);\n\n}\n\ninterface PriceExtractor {\n\ndouble apply(Product product);\n\n}<\/code><\/pre>\n<\/td>\n<td valign=\"top\">\n<pre><code class=\"language-java\">double totalPrice = 0.0;\n\nfor (Product product : products) {\n\nif (product.getPrice() &gt; 200.0) {\n\ntotalPrice += product.getPrice();\n\n}\n\n}<\/code><\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>See the brevity and conciseness in the side-by-side comparison above? Lambda expressions reduce boilerplate code, resulting in concise (and readable syntax). Developers can achieve the same functionality with fewer lines of code. The conciseness is achieved because Lambda expressions provide an expressive syntax that allows developers to focus on the core logic without unnecessary ceremony.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Benefit_2_Better_readability_%3E_better_collaboration_across_AppDev_and_SRE_and_everyone_else\"><\/span>Benefit #2: Better readability =&gt; \u00a0better collaboration across AppDev and SRE (and everyone else)<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Lambda expressions, when used judiciously, enhance the structural clarity of code. Developers can easily discern the logic encapsulated within lambda expressions. This helps in aiding bug identification and resolution in the future.<\/p>\n<p>As an example, the old-style code in the above example has more lines for conditional checks. As the business logic becomes more complex, this increased complexity may make the code harder to understand. This is true especially for developers who are new to the codebase or reviewing the code after some time.<\/p>\n<p>Lambda expressions that are clear and comprehensible help in avoiding technical debt. Code that is easy to understand is less prone to introducing complexities, reducing the likelihood of accumulating technical debt in projects.<\/p>\n<p>At the same time, developers should prioritize readability over brevity. If a Java lambda expression becomes too complex, it may hinder understanding rather than enhancing it.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Benefit_3_Encourages_functional_programming_%3E_flexible_and_modular_code\"><\/span>Benefit #3: Encourages functional programming =&gt; flexible and modular code<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>The lambda expressions example shown gets the job done with less boilerplate code. Pass a lambda expression to filter products based on the condition product.getPrice() &gt; 200.0, replacing the traditional for loop and explicit conditional statements.<\/p>\n<div style=\"padding: 20px 20px 0; border: 1px solid #ffd392; background: #fcf8ef; margin-bottom: 30px;\">\n<p>Although I have used a contrived example, real-world business logic could be far more complex, involving intricate conditions and multiple steps, where the conciseness of lambda expressions becomes even more advantageous.SREs and application developers need to be on the lookout for utilizing concise constructs, such as lambda expressions in Java 8. Positively influence your developer communities to express complex business operations in a more compact and understandable manner.<\/p>\n<\/div>\n<h3><span class=\"ez-toc-section\" id=\"Benefit_4_Improved_start-up_performance_%3E_faster_user_experience\"><\/span>Benefit #4: Improved start-up performance =&gt; faster user experience<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Anonymous classes impact start-up times of JVMs. When you use anonymous classes, the compiler generates a new class file for each one. These files typically have names like <strong>ClassName$1\u00a0<\/strong>, where ClassName is the name of the class containing the anonymous class, followed by a dollar sign and a number.<\/p>\n<p>Here\u2019s why anonymous classes impact start-up times:<\/p>\n<ul>\n<li>Each class file must be loaded and verified before it can be used.<\/li>\n<li>Loading involves operations like disk I\/O and decompressing the JAR file, which can be costly<\/li>\n<li>This process can be resource-intensive, impacting the startup performance of the application.<\/li>\n<\/ul>\n<p>As a result, the more anonymous inner classes you have, the longer it may take for your application to start up, potentially leading to a less responsive user experience. Java lambda expressions result in lesser number of classes and therefore aid in faster JVM start up times.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Benefit_5_Lean_JAR_file_sizes_%3E_faster_download_times_cost_savings\"><\/span>Benefit #5: Lean JAR file sizes =&gt; faster download times, cost savings<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>The Java compiler generates multiple classes during compilation time. These classes contribute to JAR file bloat, leading to larger JAR file sizes. A JAR (Java Archive) file is a compressed file format that bundles Java class files, metadata, and resources into a single package. It allows developers to conveniently distribute and deploy Java applications or libraries, simplifying the management and sharing of Java code.<\/p>\n<p>Bloated JAR files have several consequences:<\/p>\n<ul>\n<li><strong>Quicker download times:<\/strong> Smaller JAR files download faster over networks. This is crucial especially in scenarios with limited bandwidth.<\/li>\n<li><strong>Better deployment cycles:<\/strong> Compact JAR files are more efficient for deployment. They consume less disk space, facilitating quicker distribution and deployment processes, which is crucial in large-scale software distribution.<\/li>\n<li><strong>Consumes less storage space:<\/strong> Especially important for resource-constrained devices.<\/li>\n<li><strong>Cost Savings in bandwidth:<\/strong> Reduced JAR file sizes result in lower bandwidth consumption. This is true for cloud-based deployments where data transfer costs are a consideration.<\/li>\n<\/ul>\n<div style=\"padding: 20px 20px 0; border: 1px solid #ffd392; background: #fcf8ef; margin-bottom: 30px;\">\n<p>In Function as a Service (FaaS) environments such as AWS Lambda (not to be confused with Java lambda), lean JAR files are essential. Compact JARs facilitate faster deployment, reduce startup times, and improve the overall efficiency of serverless functions.<\/p>\n<p>This is crucial in FaaS, where cold-starts are a concern. Quick execution and resource optimization are key for responsive and cost-effective serverless applications.<\/p>\n<\/div>\n<h3><span class=\"ez-toc-section\" id=\"Benefit_6_Memory_efficient_metaspace_%3E_optimized_memory\"><\/span>Benefit #6: Memory efficient (metaspace) =&gt; optimized memory<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<div style=\"padding: 20px 20px 0; border: 1px solid #ffd392; background: #fcf8ef; margin-bottom: 30px;\">\n<p style=\"margin-bottom: 10px;\"><b>What is metaspace?<\/b><\/p>\n<p>Metaspace is a memory area in the JVM that serves as a storage location for metadata related to class definitions. Metaspace is responsible for storing information such as class names, method signatures, and constant pool data, essential for the runtime execution of Java programs. Metaspace replaced the Permanent Generation (PermGen) in Java 8.<\/p>\n<\/div>\n<p>Unlike PermGen, metaspace can dynamically adjust its size, avoiding common issues like OutOfMemoryErrors. Nevertheless, the instantiation of multiple anonymous classes can still contribute to increased metaspace usage.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter \" src=\"https:\/\/www.eginnovations.com\/blog\/wp-content\/uploads\/2024\/02\/Lambda-used-memory.webp\" align=\"center\" \/><\/p>\n<div class=\"img_caption\">As SRE, you need the ability to see historical trends of metaspace utilization to detect anomalies.<br \/>\nThe above is an example from eG Enterprise JVM observability suite.<\/div>\n<p>The bottomline is that Lambda expressions take up less room in metaspace as compared to anonymous classes.<\/p>\n<div style=\"border-top: 2px solid #ffd392; border-bottom: 2px solid #ffd392; padding: 10px 0; margin-bottom: 20px;\">\n<p style=\"font-size: 1.5em; line-height: 1.5em;\"><em>The benefit of using lambda expressions also extends to heap memory. You get quicker and more efficient GC (garbage collection) and lesser GC pause times. <\/em><\/p>\n<p style=\"font-size: 1.5em; line-height: 1.5em; margin-bottom: 0px;\"><em>This is because a smaller number of objects are created or instantiated in memory as compared to anonymous classes. Therefore, less garbage to reclaim from heap memory.<\/em><\/p>\n<\/div>\n<h3><span class=\"ez-toc-section\" id=\"Benefit_7_Code_cache_efficient_%3E_stable_applications\"><\/span>Benefit #7: Code cache efficient =&gt; stable applications<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<div style=\"padding: 20px 20px 0; border: 1px solid #fcf8ef; background: #fcf8ef; margin-bottom: 30px;\">\n<p style=\"margin-bottom: 10px;\"><b>What is code cache and what bad things happen when it becomes full?<\/b><\/p>\n<p>Code cache stores compiled native code generated by the Just-In-Time (JIT) compiler, enhancing execution speed. By writing efficient and concise code, developers can maximize code cache utilization, leading to quicker execution and improved overall application responsiveness.<\/p>\n<p>Bad things happen when the code cache becomes full in the Java Virtual Machine (JVM):<\/p>\n<ul>\n<li><strong>Compiler Disabling:<\/strong> The JVM stops compiling additional bytecode into native code, leading to a significant performance degradation.<\/li>\n<li><strong>Warning Messages:<\/strong> You\u2019ll start to see warning messages such as &#8220;CodeCache is full\u2026 The compiler has been disabled.&#8221;<\/li>\n<li><strong>Application Performance Degradation:<\/strong> The application&#8217;s performance degrades as it relies solely on interpreted bytecode, which is typically slower than native code.<\/li>\n<li><strong>Application Crashes:<\/strong> In extreme cases, if the code cache-related issues are not addressed, the application might eventually crash due to the inability to allocate memory for compiling and storing native code.<\/li>\n<\/ul>\n<\/div>\n<p>Since the code inside each anonymous class is compiled to machine code by the JVM, it would be stored inside a code cache. More code = more code cache bloat.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter \" src=\"https:\/\/www.eginnovations.com\/blog\/wp-content\/uploads\/2024\/02\/Lambda-used-percentage.webp\" align=\"center\" \/><\/p>\n<div class=\"img_caption\">Visualizing historical trends in code cache utilization is vital for anomaly detection.<br \/>\nThe above screenshot is also from eG Enterprise JVM observability suite.<\/div>\n<p>Again, lambda expressions are simply more code cache efficient when compared to anonymous classes.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Why_are_Java_lambda_expressions_hard_to_instrument_for_tracing_and_monitoring\"><\/span>Why are Java lambda expressions hard to instrument for tracing and monitoring?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p><a href=\"https:\/\/www.eginnovations.com\/glossary\/application-performance-monitoring\">APM<\/a> and observability tools instrument Java applications by hooking into the JVM at the time of <em>bytecode class loading<\/em>. For observability instrumentation engineers, understanding the class loading\u00a0 process is key.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Reason_1_Needs_advanced_instrumentation_techniques\"><\/span>Reason #1: Needs advanced instrumentation techniques<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>When it comes to \u201cnormal\u201d Java classes vs Java lambda expressions, there&#8217;s a big difference in the class loading process.<\/p>\n<p>In normal class loading, the bytecode is loaded via the &#8220;transform&#8221; method. However, for Java lambda expressions, the Java bytecode is loaded via the \u201cbootstrap\u201d method. This adds complexity to the instrumentation process.<\/p>\n<p><a href=\"https:\/\/www.eginnovations.com\/blog\/wp-content\/uploads\/2024\/02\/java-chart-2-zoom.jpg\" data-rel=\"lightbox-image-1\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"> <img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-34016\" src=\"https:\/\/www.eginnovations.com\/blog\/wp-content\/uploads\/2024\/02\/java-chart-2-eg.webp\" alt=\"\" width=\"850\" height=\"189\" \/><\/a><\/p>\n<p>The APM instrumentation engineer often must figure out how to use specialized techniques to instrument the bootstrap process.<\/p>\n<p>The Lambda bootstrap method uses the InnerClassLambdaMetafactory to generate an inner class for the lambda at runtime. Observability tools must intercept this method and capture the method argument \u201cclassBytes\u201d &amp; modify it using advanced techniques such as ASM to check whether that bytecode matches with configured functional interface names.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Reason_2_Java_lambda_expressions_bytecode_vary_from_one_JVM_vendor_to_another\"><\/span>Reason #2: Java lambda expressions bytecode vary from one JVM vendor to another<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Each version of the JVM employs a different implementation of the bootstrap method. This also adds to the complexity of instrumenting the Java application.<\/p>\n<p>Here are some examples of the additional complexity:<\/p>\n<p><strong>Java version 9 to 14<\/strong><\/p>\n<pre><code class=\"language-java\">jdk.internal.misc.Unsafe. defineAnonymousClass(Class, byte[] , Object)<\/code><\/pre>\n<p><strong>Java version 15 to 20<\/strong><\/p>\n<pre><code class=\"language-java\">java.lang.invoke.MethodHandles$Lookup.defineHiddenClass(byte[], boolean, ClassOption\u2026);<\/code><\/pre>\n<p><strong>On Java version 21<\/strong><\/p>\n<pre><code class=\"language-java\">java.lang.invoke.MethodHandles$Lookup.makeHiddenClassDefiner(String, byte[], Set, ClassFileDumper);<\/code><\/pre>\n<h2><span class=\"ez-toc-section\" id=\"Beware_blind_spots_in_your_APM_and_observability_tools\"><\/span>Beware blind spots in your APM and observability tools<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>What happens when your APM tool lacks Java lambda instrumentation and visibility, but your Java application indeed uses lambda expressions?<\/p>\n<p>You could end up with incomplete traces.\u00a0 If a Lambda makes external calls like JMS or third-party calls, missing instrumentation leads to gaps in distributed traces. This results in blindness to slowdowns in dependencies, creating black boxes that hinder root-cause analysis.<\/p>\n<p>You might also see un-instrumented time blocks in code-level call graphs that indicate parts not covered by your observability tool.<\/p>\n<p><a href=\"https:\/\/www.eginnovations.com\/blog\/wp-content\/uploads\/2024\/02\/image-3-zoom-1.jpg\" data-rel=\"lightbox-image-2\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-33973\" src=\"https:\/\/www.eginnovations.com\/blog\/wp-content\/uploads\/2024\/02\/image-3-1.webp\" alt=\"\" width=\"750\" height=\"425\" srcset=\"https:\/\/www.eginnovations.com\/blog\/wp-content\/uploads\/2024\/02\/image-3-1.webp 750w, https:\/\/www.eginnovations.com\/blog\/wp-content\/uploads\/2024\/02\/image-3-1-300x170.webp 300w, https:\/\/www.eginnovations.com\/blog\/wp-content\/uploads\/2024\/02\/image-3-1-310x176.webp 310w, https:\/\/www.eginnovations.com\/blog\/wp-content\/uploads\/2024\/02\/image-3-1-140x79.webp 140w\" sizes=\"auto, (max-width: 750px) 100vw, 750px\" \/><\/a><\/p>\n<div style=\"font-size: 1.5em; border-top: 2px solid #ffd392; border-bottom: 2px solid #ffd392; line-height: 1.5em; padding: 10px 0; margin-bottom: 20px;\"><em>Blind spots in your observability tooling can cripple your ability to troubleshoot slowness and errors.<\/em><\/div>\n<h2><span class=\"ez-toc-section\" id=\"As_an_SRE_and_IT_Ops_select_APM_and_observability_tools_with_care\"><\/span>As an SRE and IT Ops, select APM and observability tools with care<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>As an SRE, opt for tools that employ sophisticated instrumentation tailored for Java lambda expressions. One such example is eG Enterprise which gives you full-stack visibility into Java applications that use lambda expressions inside the code.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-33975\" src=\"https:\/\/www.eginnovations.com\/blog\/wp-content\/uploads\/2024\/02\/image-4.webp\" alt=\"\" width=\"750\" height=\"449\" srcset=\"https:\/\/www.eginnovations.com\/blog\/wp-content\/uploads\/2024\/02\/image-4.webp 750w, https:\/\/www.eginnovations.com\/blog\/wp-content\/uploads\/2024\/02\/image-4-300x180.webp 300w, https:\/\/www.eginnovations.com\/blog\/wp-content\/uploads\/2024\/02\/image-4-310x186.webp 310w, https:\/\/www.eginnovations.com\/blog\/wp-content\/uploads\/2024\/02\/image-4-140x84.webp 140w\" sizes=\"auto, (max-width: 750px) 100vw, 750px\" \/><\/p>\n<p>Unlike legacy monitoring tools that often necessitate code changes for debugging or troubleshooting data, modern tools, such as eG Enterprise, are Java Lambda Expression-aware. In my recent article on monitoring Java Lambda Expressions, I highlighted the challenge: many SRE and IT Ops tools lack diagnostic capabilities for this powerful code construct.<\/p>\n<p>All this means that legacy monitoring tools often require changes to code or the way code is built to be made to obtain debug or troubleshooting data. And of course, for the SRE or IT Ops team this isn\u2019t SREs are often simply handed third-party apps or apps developed by a siloed AppDev teams. Changing application code in order to gain observability insight is not feasible in many cases. Automatic observability tools such as eG Enterprise solve this problem out of the box.<\/p>\n<p>It&#8217;s essential for SRE and IT Ops teams to prioritize tools that understand and support modern code constructs to simplify troubleshooting in contemporary applications. For further details and insights, visit <a href=\"https:\/\/www.eginnovations.com\/blog\/is-your-java-observability-tool-lambda-expressions-aware\/\/\">Is your Java Observability tool Lambda Expressions aware?<\/a>.<\/p>\n<p>Ignoring this consideration could lead to significant challenges in effectively monitoring and troubleshooting modern applications, particularly those leveraging Java Lambda Expressions.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Whats_the_takeaway_for_SREs_and_IT_Ops_teams\"><\/span>What&#8217;s the takeaway for SREs and IT Ops teams?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>I\u2019ve posted some of this information <a href=\"https:\/\/www.linkedin.com\/posts\/arun-aravamudhan_q-as-an-sre-or-it-ops-operations-pro-activity-7129755558621958145-SDsh?utm_source=share&amp;utm_medium=member_desktop\">on LinkedIn<\/a> and discussed how SREs are often too abstracted away from language features which have an impact on performance. By the time SREs get to know about it, it\u2019s usually too late in the game. One SRE commented:<\/p>\n<p><em>\u201cHow do you go about discussing this with the dev team, considering that SREs are not directly responsible for the application design and code development? Isn&#8217;t this more of a task for performance engineers\u201d<\/em><\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-large wp-image-33976\" src=\"https:\/\/www.eginnovations.com\/blog\/wp-content\/uploads\/2024\/02\/lamba-over-the-wall.jpg\" alt=\"\" \/><\/p>\n<p>As an SRE, having the tools to swim upstream (or shift-left) and influence AppDev teams to use performance efficient language features would be utopia. With eG Enterprise you will at least have the tools to troubleshoot efficiently and prove when the responsibility is in the AppDev team\u2019s court.<\/p>\n<p>However, it will also give a few SREs (perhaps those with previous coding experience or in less siloed organizations) the tools to open a collaborative conversation, perhaps along the lines:<\/p>\n<p><em>&#8220;Hey folks, we saw that our Permgen and codecache is seeing some inefficiencies. In looking through the traces in observability, we are thinking we could do better with using the new Java language features like lambda. We can help pitch in with some before-vs-after load test benchmarks if you folks are game!&#8221;<\/em><\/p>\n<p>The key takeaway for Site Reliability Engineers (SREs) and IT Ops teams is the critical importance of being attuned to language features, such as Java Lambdas, that can significantly impact performance.<\/p>\n<p>Often, SREs may be abstracted from these nuances<em> until it&#8217;s too late<\/em>. Engaging with the development team becomes crucial, even if SREs aren&#8217;t directly responsible for application design and code development.<\/p>\n<p>This collaboration ensures that performance considerations are addressed early in the development process. While performance engineers may lead specific efforts, fostering communication between SREs and developers allows for a proactive approach to identifying and resolving potential issues related to Java Lambdas. Understanding and discussing these language features can lead to more efficient, reliable, and performant applications in the long run.<\/p>\n<p>For this collaboration to happen, SREs and IT Ops must choose <a href=\"https:\/\/www.eginnovations.com\/product\/application-performance-monitoring\">APM and observability vendors<\/a> that are modern Java ready.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Learn_More\"><\/span>Learn More<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<ul>\n<li>Read my earlier article on guidance for SRE and IT Ops teams tasked with troubleshooting Java applications including Lambda Expressions, See: <a href=\"https:\/\/www.eginnovations.com\/blog\/is-your-java-observability-tool-lambda-expressions-aware\/\">Is your Java Observability tool Lambda Expressions aware?<br \/>\n<\/a><\/li>\n<li>Learn about distributed tracing technologies which can be used when deploying and monitoring Java applications, see: <a href=\"https:\/\/www.eginnovations.com\/glossary\/distributed-tracing\">What is Distributed Tracing? &#8211; IT Glossary | eG Innovations<\/a><\/li>\n<li>For information on eG Enterprise\u2019s support for Java stacks, see: <a href=\"https:\/\/www.eginnovations.com\/supported-technologies\/java-application-monitoring\">Java Application Monitoring<\/a><\/li>\n<\/ul>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>SUMMARY SRE and IT Operations play a critical role in ensuring reliable, high-performance applications. Yet, SREs (Site Reliability Engineers) often face &#8216;thrown-over-the-wall&#8217; code deployments to operate without having insights into the code-level features. In my previous article (\u201cIs your Java Observability tool Lambda Expressions aware?&#8221;), I delved into one such code-level feature: Java lambda expressions [&hellip;]<\/p>\n","protected":false},"author":8,"featured_media":33959,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"_lmt_disableupdate":"yes","_lmt_disable":"","footnotes":""},"categories":[27],"tags":[629,52,1970,493,1155,602,1389,177,1271,1304,555,2124],"class_list":["post-33945","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-java-monitoring","tag-apm-tools","tag-application-performance-monitoring","tag-code-level-analysis","tag-code-level-monitoring","tag-devops-and-sres","tag-java-code","tag-java-code-analysis","tag-java-performance","tag-java-performance-monitoring","tag-java-tracing","tag-java-troubleshooting","tag-lambda-expressions"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Demystifying Java Lambda Expressions | eG Innovations<\/title>\n<meta name=\"description\" content=\"Java lambda expressions represent an anonymous block of code as an expression or a series of statements, ultimately returning a result.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.eginnovations.com\/blog\/demystifying-java-lambda-expressions\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Demystifying Java Lambda Expressions | eG Innovations\" \/>\n<meta property=\"og:description\" content=\"Java lambda expressions represent an anonymous block of code as an expression or a series of statements, ultimately returning a result.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.eginnovations.com\/blog\/demystifying-java-lambda-expressions\/\" \/>\n<meta property=\"og:site_name\" content=\"eG Innovations\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/eGInnovations\" \/>\n<meta property=\"article:published_time\" content=\"2024-02-29T17:51:19+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.eginnovations.com\/blog\/wp-content\/uploads\/2024\/02\/jaba-social.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"628\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Arun Aravamudhan\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@https:\/\/x.com\/perfclarity\" \/>\n<meta name=\"twitter:site\" content=\"@eginnovations\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Arun Aravamudhan\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"17 minutes\" \/>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Demystifying Java Lambda Expressions | eG Innovations","description":"Java lambda expressions represent an anonymous block of code as an expression or a series of statements, ultimately returning a result.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.eginnovations.com\/blog\/demystifying-java-lambda-expressions\/","og_locale":"en_US","og_type":"article","og_title":"Demystifying Java Lambda Expressions | eG Innovations","og_description":"Java lambda expressions represent an anonymous block of code as an expression or a series of statements, ultimately returning a result.","og_url":"https:\/\/www.eginnovations.com\/blog\/demystifying-java-lambda-expressions\/","og_site_name":"eG Innovations","article_publisher":"https:\/\/www.facebook.com\/eGInnovations","article_published_time":"2024-02-29T17:51:19+00:00","og_image":[{"width":1200,"height":628,"url":"https:\/\/www.eginnovations.com\/blog\/wp-content\/uploads\/2024\/02\/jaba-social.jpg","type":"image\/jpeg"}],"author":"Arun Aravamudhan","twitter_card":"summary_large_image","twitter_creator":"@https:\/\/x.com\/perfclarity","twitter_site":"@eginnovations","twitter_misc":{"Written by":"Arun Aravamudhan","Est. reading time":"17 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.eginnovations.com\/blog\/demystifying-java-lambda-expressions\/#article","isPartOf":{"@id":"https:\/\/www.eginnovations.com\/blog\/demystifying-java-lambda-expressions\/"},"author":{"name":"Arun Aravamudhan","@id":"https:\/\/www.eginnovations.com\/blog\/#\/schema\/person\/d788cb81df96a940429c3f5a3b294a6a"},"headline":"Demystifying Java Lambda Expressions","datePublished":"2024-02-29T17:51:19+00:00","mainEntityOfPage":{"@id":"https:\/\/www.eginnovations.com\/blog\/demystifying-java-lambda-expressions\/"},"wordCount":3301,"publisher":{"@id":"https:\/\/www.eginnovations.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.eginnovations.com\/blog\/demystifying-java-lambda-expressions\/#primaryimage"},"thumbnailUrl":"https:\/\/www.eginnovations.com\/blog\/wp-content\/uploads\/2024\/02\/java-top.jpg","keywords":["APM Tools","application performance monitoring","Code level analysis","code level monitoring","devops and SREs","Java code","java code analysis","Java performance","Java performance monitoring","java tracing","Java troubleshooting","Lambda Expressions"],"articleSection":["Java Monitoring"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.eginnovations.com\/blog\/demystifying-java-lambda-expressions\/","url":"https:\/\/www.eginnovations.com\/blog\/demystifying-java-lambda-expressions\/","name":"Demystifying Java Lambda Expressions | eG Innovations","isPartOf":{"@id":"https:\/\/www.eginnovations.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.eginnovations.com\/blog\/demystifying-java-lambda-expressions\/#primaryimage"},"image":{"@id":"https:\/\/www.eginnovations.com\/blog\/demystifying-java-lambda-expressions\/#primaryimage"},"thumbnailUrl":"https:\/\/www.eginnovations.com\/blog\/wp-content\/uploads\/2024\/02\/java-top.jpg","datePublished":"2024-02-29T17:51:19+00:00","description":"Java lambda expressions represent an anonymous block of code as an expression or a series of statements, ultimately returning a result.","breadcrumb":{"@id":"https:\/\/www.eginnovations.com\/blog\/demystifying-java-lambda-expressions\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.eginnovations.com\/blog\/demystifying-java-lambda-expressions\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.eginnovations.com\/blog\/demystifying-java-lambda-expressions\/#primaryimage","url":"https:\/\/www.eginnovations.com\/blog\/wp-content\/uploads\/2024\/02\/java-top.jpg","contentUrl":"https:\/\/www.eginnovations.com\/blog\/wp-content\/uploads\/2024\/02\/java-top.jpg","width":362,"height":235},{"@type":"BreadcrumbList","@id":"https:\/\/www.eginnovations.com\/blog\/demystifying-java-lambda-expressions\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.eginnovations.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Demystifying Java Lambda Expressions"}]},{"@type":"WebSite","@id":"https:\/\/www.eginnovations.com\/blog\/#website","url":"https:\/\/www.eginnovations.com\/blog\/","name":"eG Innovations","description":"IT Performance Monitoring Insights","publisher":{"@id":"https:\/\/www.eginnovations.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.eginnovations.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.eginnovations.com\/blog\/#organization","name":"eG Innovations","alternateName":"eg innovations","url":"https:\/\/www.eginnovations.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.eginnovations.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.eginnovations.com\/blog\/wp-content\/uploads\/2014\/07\/eg-logo-dark-gray1_new.jpg","contentUrl":"https:\/\/www.eginnovations.com\/blog\/wp-content\/uploads\/2014\/07\/eg-logo-dark-gray1_new.jpg","width":362,"height":235,"caption":"eG Innovations"},"image":{"@id":"https:\/\/www.eginnovations.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/eGInnovations","https:\/\/x.com\/eginnovations"]},{"@type":"Person","@id":"https:\/\/www.eginnovations.com\/blog\/#\/schema\/person\/d788cb81df96a940429c3f5a3b294a6a","name":"Arun Aravamudhan","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.eginnovations.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/7ff42334d908fb4060880a4487331e4a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/7ff42334d908fb4060880a4487331e4a?s=96&d=mm&r=g","caption":"Arun Aravamudhan"},"sameAs":["https:\/\/www.linkedin.com\/in\/arun-aravamudhan\/","https:\/\/x.com\/https:\/\/x.com\/perfclarity"],"url":"https:\/\/www.eginnovations.com\/blog\/author\/arun-aravamudhan\/"}]}},"modified_by":"eG Innovations","_links":{"self":[{"href":"https:\/\/www.eginnovations.com\/blog\/wp-json\/wp\/v2\/posts\/33945","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.eginnovations.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.eginnovations.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.eginnovations.com\/blog\/wp-json\/wp\/v2\/users\/8"}],"replies":[{"embeddable":true,"href":"https:\/\/www.eginnovations.com\/blog\/wp-json\/wp\/v2\/comments?post=33945"}],"version-history":[{"count":0,"href":"https:\/\/www.eginnovations.com\/blog\/wp-json\/wp\/v2\/posts\/33945\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.eginnovations.com\/blog\/wp-json\/wp\/v2\/media\/33959"}],"wp:attachment":[{"href":"https:\/\/www.eginnovations.com\/blog\/wp-json\/wp\/v2\/media?parent=33945"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.eginnovations.com\/blog\/wp-json\/wp\/v2\/categories?post=33945"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.eginnovations.com\/blog\/wp-json\/wp\/v2\/tags?post=33945"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}