Recently, I shared a deep dive into how Spring, Lombok, and Mockito manipulate bytecode from inside the JVM. But I didn’t stop there. The next logical step was to put that knowledge into practice: I built a working example that shows how to modify a running Java application — without restarts, without redeployments, and without touching a single line of the original source code. In my new article, I walk through: ✅ How to attach to a live JVM using the Attach API ✅ How to load a Java agent and gain full access to Instrumentation ✅ How to redefine a method body at runtime ✅ Common pitfalls and practical solutions This isn’t just theory — it’s a fully functional implementation you can run and adapt to your own use cases. After reading both articles — the one on how popular frameworks work under the hood, and this one on dynamic JVM instrumentation — you’ll be able to stop seeing the JVM as a black box. Instead, you’ll start seeing it as a flexible platform that can be programmed from the outside, even while your application is already running. 👉 Full article on TProger (in Russian, with code): https://lnkd.in/epVsA8Rq #Java #JVM #Bytecode #HotSwap #Instrumentation #SoftwareEngineering #ByteBuddy #APM #Performance #Programming
How to modify a running Java application without restarts
More Relevant Posts
-
How Java Really Works: From Code to Execution Magic ⚙️ Ever wondered what happens under the hood when you hit Run on your Java program? Here’s the breakdown: 🔹 Compilation Phase: Your .java source files are compiled by javac into platform-independent bytecode (.class) — this bytecode isn’t tied to any specific OS or CPU. 🔹 Class Loading & Verification: When you execute your program, the ClassLoader dynamically loads the bytecode into the JVM, verifying its structure, access rights, and memory safety before execution. 🔹 Execution Phase: Inside the JVM, the Interpreter initially runs the bytecode line by line. But as execution continues, the Just-In-Time (JIT) Compiler identifies “hot” methods (frequently executed code paths) and compiles them into native machine code for blazing-fast performance. 🔹 Memory Management & Runtime Services: Meanwhile, the Garbage Collector (GC) reclaims unused memory, JIT optimizations inline hot paths, and runtime profiling continuously tunes performance. 💡 In essence — Java bridges portability and performance through the JVM’s layered architecture, blending interpretation, compilation, and runtime intelligence into one elegant engine. #Java #JVM #JIT #Programming #FullStackDeveloper #SpringBoot #SoftwareEngineering #Performance #BackendDevelopment
To view or add a comment, sign in
-
-
SonarQube and other cyclomatic complexity scanners are great at making developers create more understandable code! It means that code reviewer's don't have to argue with writer if some function is obviously too complex! The cyclomatic test will do it for you. But specifically for Rust's ?(error operator) and Golang's if err != nil{ return err } I don't believe there is any actual cognitive load with having to say, yep, I don't want to handle a problem from this function call, just pop error up the stack. I personally wish those two cases were skipped from the complexity score. I believe this would allow go code to be approximately the same complexity as java, because similar java often would throw an exception which doesn't have to be handled by every function layer. What do you think?
To view or add a comment, sign in
-
-
💡 𝗝𝗮𝘃𝗮/𝐒𝐩𝐫𝐢𝐧𝐠 𝐁𝐨𝐨𝐭 𝗧𝗶𝗽 - 𝗥𝗲𝗰𝗼𝗿𝗱 𝗣𝗮𝘁𝘁𝗲𝗿𝗻𝘀 🔥 💎 𝗪𝗵𝗮𝘁 𝗮𝗿𝗲 𝗥𝗲𝗰𝗼𝗿𝗱 𝗣𝗮𝘁𝘁𝗲𝗿𝗻𝘀? Finalized in 𝗝𝗮𝘃𝗮 𝟮𝟭 through JEP 440, record patterns allow you to deconstruct record components directly in pattern matching. Instead of calling accessor methods manually, you can unpack record fields in a single, expressive line of code. ⚡ 𝗪𝗵𝘆 𝗨𝘀𝗲 𝗧𝗵𝗲𝗺? Before Java 21, working with records required verbose instanceof checks followed by manual accessor calls for each component. Record patterns eliminate this boilerplate by letting you extract values directly in the pattern itself, making your code cleaner and more maintainable. ✅ 𝗞𝗲𝘆 𝗕𝗲𝗻𝗲𝗳𝗶𝘁𝘀 ◾ 𝗗𝗶𝗿𝗲𝗰𝘁 𝗗𝗲𝗰𝗼𝗻𝘀𝘁𝗿𝘂𝗰𝘁𝗶𝗼𝗻: Extract record components without accessor methods. ◾ 𝗡𝗲𝘀𝘁𝗲𝗱 𝗣𝗮𝘁𝘁𝗲𝗿𝗻𝘀: Handle complex nested records in one line. ◾ 𝗦𝘄𝗶𝘁𝗰𝗵 𝗦𝘂𝗽𝗽𝗼𝗿𝘁: Use record patterns directly in switch expressions 🤔 𝗔𝗿𝗲 𝘆𝗼𝘂 𝘂𝘀𝗶𝗻𝗴 𝗿𝗲𝗰𝗼𝗿𝗱 𝗽𝗮𝘁𝘁𝗲𝗿𝗻𝘀 𝗶𝗻 𝘆𝗼𝘂𝗿 𝗽𝗿𝗼𝗷𝗲𝗰𝘁𝘀 𝘆𝗲𝘁? #java #springboot #programming #softwareengineering #softwaredevelopment
To view or add a comment, sign in
-
-
💡𝗝𝗮𝘃𝗮 𝗧𝗶𝗽/𝐒𝐩𝐫𝐢𝐧𝐠 𝐁𝐨𝐨𝐭 𝐓𝐢𝐩 - 𝗜𝗻𝘀𝘁𝗮𝗻𝗰𝗲𝗼𝗳 𝗣𝗮𝘁𝘁𝗲𝗿𝗻 𝗠𝗮𝘁𝗰𝗵𝗶𝗻𝗴 🔥 💎 𝗪𝗵𝗮𝘁 𝗶𝘀 𝗶𝘁? Pattern matching with instanceof (Java 16+) lets you test an object's type AND declare a new variable in one step. When the pattern matches, the variable is automatically cast and assigned. This eliminates redundant casting and makes your code more concise. ✅ 𝗞𝗲𝘆 𝗕𝗲𝗻𝗲𝗳𝗶𝘁𝘀 ◾ Combines type checking and variable declaration in a single expression. ◾ Eliminates explicit casting and reduces boilerplate code. ◾ Prevents ClassCastException with compile-time safety. ⚡ 𝗖𝗼𝗺𝗺𝗼𝗻 𝗨𝘀𝗲 𝗖𝗮𝘀𝗲𝘀 ◾ Type checking in if statements: if (obj instanceof String str). ◾ Switch expressions with pattern matching (Java 21+). ◾ Processing collections with different element types. 🤔 Do you use pattern matching in your code? #java #springboot #programming #softwareengineering #softwaredevelopment
To view or add a comment, sign in
-
-
🚀 Day 43 of #100DaysOfCode – Striver’s DSA Sheet 🚀 ✅ Topic Covered Today: Queue – Basic Implementation Using Java JCF 💡 Lesson of the Day (Approach-Focused): 🧠 Basic Queue Implementation (Java JCF) Today, I revised how queues work internally and how Java’s Queue interface helps implement FIFO operations efficiently using LinkedList. 🔹 Operations Covered: add() → Insert element at the rear poll() → Remove element from the front peek() → Access the front element isEmpty() → Check if the queue is empty size() → Get current size of queue All operations follow the FIFO Principle (First In, First Out). 🔹 Approach & Understanding: Queue does not support indexing → traversal happens sequentially. LinkedList is commonly used because insertion and deletion at ends are O(1). Helps build intuition for problems like sliding window, BFS, task scheduling, and producer-consumer logic. 🧮 Time Complexity: Enqueue (add): O(1) Dequeue (poll): O(1) Peek: O(1) Traversal: O(n) 💾 Space Complexity: O(n) for storing elements in queue. 💭 Learning: Revisiting how Queue works through JCF helped reinforce the fundamentals of FIFO behavior, which is essential before diving into advanced queue-based problems. #100DaysOfCode #DSA #StriversSheet #Java #Queue #JCF #ProblemSolving #CodingJourney #LogicBuilding #Consistency
To view or add a comment, sign in
-
-
🚀 Day 94 of #100DaysOfCode Today, I explored one of the most interesting and practical concepts in Java Concurrency and System Design -creating a Thread-Safe Singleton Logger using Double-Checked Locking. 🧩 Problem Statement: Design a Thread-safe Singleton Logger that ensures: ✅ Only one instance of the logger exists across multiple threads. ✅ Log messages are written to both the console and a log file. ✅ Proper synchronization and lazy initialization are maintained. ✅ Avoids performance bottlenecks caused by unnecessary synchronization. I implemented this by using: Volatile keyword → To ensure visibility across threads. Private constructor → To restrict object creation. Double-checked locking pattern → To achieve thread-safe lazy initialization efficiently. Synchronized log method → To ensure only one thread writes at a time. 🧠 Key Learning Points: Understood how wait() and notifyAll() differ from synchronized blocks in concurrency control. Explored the role of the volatile keyword in preventing instruction reordering. Learned the importance of handling I/O operations safely in a multithreaded environment. Reinforced the concept of Singleton Pattern in real-world logging systems. 🧵 Output Validation: Created two threads (Thread-1 and Thread-2), both logging multiple messages concurrently. The logger ensured that all messages were written in order, without duplication or corruption -both to the console and the file application.log. ✨ Skills Practiced: Java Concurrency Thread Synchronization Design Patterns (Singleton) File Handling in Java System Design Fundamentals Every day brings a new layer of understanding to how scalable, thread-safe systems work behind the scenes. #100DaysOfCode #Java #SystemDesign #Multithreading #Concurrency #SoftwareEngineering #LearningJourney #CodingChallenge #JavaDeveloper #OOPs #DesignPatterns
To view or add a comment, sign in
-
-
@Component vs @Bean @Component marks a class for automatic bean detection via scanning. @Bean defines a bean manually inside a @Configuration class. Use @Component for simple POJOs and services. Use @Bean when you need full control over object creation. Both ultimately register beans in the Spring container. #SpringFramework #Java #SoftwareEngineering #BackendDevelopment
To view or add a comment, sign in
-
💡 Java Bytecode vs JIT: Why Your Code Gets Faster in Production Many developers get confused: “Isn’t my Java code already compiled? Why does my APIs respond quicker after the first hit” Here’s the scoop: 1️⃣ Compilation with javac Your Java code → bytecode (.class files) Platform-independent, portable No runtime optimizations yet 2️⃣ JVM Execution Interpreter: Executes bytecode line by line → slow JIT Compiler (Just-In-Time): Observes running code → compiles hot spots to optimized machine code JIT Optimizations Include 🔁 Method Inlining 🎯 Devirtualization (virtual → direct calls) 🔄 Loop Unrolling 📊 Escape Analysis (stack allocation) 🔒 Lock Elision 3️⃣ Result Bytecode = blueprint JIT = runtime optimizer Your code evolves based on real usage → often much faster after warm-up Key Takeaway: Production speed ≠ initial speed. The JVM is continuously making your code smarter. 🚀 #Java #JVM #JIT #PerformanceEngineering #Programming #TechInsights
To view or add a comment, sign in
-
💡 𝗝𝗮𝘃𝗮/𝐒𝐩𝐫𝐢𝐧𝐠 𝐁𝐨𝐨𝐭 𝗧𝗶𝗽 - 𝗦𝘄𝗶𝘁𝗰𝗵 𝗘𝘅𝗽𝗿𝗲𝘀𝘀𝗶𝗼𝗻 💎 🕯 𝗧𝗿𝗮𝗱𝗶𝘁𝗶𝗼𝗻𝗮𝗹 𝗦𝘄𝗶𝘁𝗰𝗵 𝗦𝘁𝗮𝘁𝗲𝗺𝗲𝗻𝘁 The traditional switch statement has been part of Java since the beginning. It requires explicit break statements to prevent fall-through, which can lead to bugs if forgotten. Each case must contain statements that execute sequentially, making the code verbose and error-prone. 💡 𝗠𝗼𝗱𝗲𝗿𝗻 𝗦𝘄𝗶𝘁𝗰𝗵 𝗘𝘅𝗽𝗿𝗲𝘀𝘀𝗶𝗼𝗻 Switch expressions were introduced in Java 14 as a more concise and safe alternative. Using the -> syntax, you eliminate the need for break statements and can directly return values. Multiple cases can be grouped with commas, and the compiler enforces exhaustiveness for better safety. ✅ 𝗞𝗲𝘆 𝗕𝗲𝗻𝗲𝗳𝗶𝘁𝘀 ◾ No break statements, safer and cleaner code. ◾ Direct value assignment, treat switch as an expression. ◾ Multiple labels with comma separation. ◾ Compiler exhaustiveness checks, fewer runtime errors. 🤔 Which one do you prefer? #java #springboot #programming #softwareengineering #softwaredevelopment
To view or add a comment, sign in
-
More from this author
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development