Spent 15 minutes wondering why my Spring Boot application was not picking up environment variables. The code looked fine: @Value("${API_KEY}") private String apiKey; No errors. App started fine. But apiKey was always null. The problem: Environment variables use underscores, but Spring expects dots in property names by default. The fix: Use relaxed binding or set it correctly in application-properties. spring.application.api-key=${API_KEY} Then inject it: @Value("${spring.application.api-key}") private String apiKey; One mapping. That was it. Spring does not warn you when it cannot resolve an environment variable. It just injects null and moves on. What environment variable issue has caught you off guard? #Java #SpringBoot #Debugging #BackendDevelopment
Spring Boot Environment Variable Issue: Fixing Null API Key
More Relevant Posts
-
🚀 Spring Boot Series #006 Spring Bean Lifecycle — The Hidden Magic Behind Your Application Ever wondered what really happens when your Spring Boot app starts? It’s not just objects being created… it’s a well-orchestrated lifecycle 🔄 Let’s break it down 👇 🔹 1. 𝗕𝗲𝗮𝗻 𝗜𝗻𝘀𝘁𝗮𝗻𝘁𝗶𝗮𝘁𝗶𝗼𝗻 Spring creates the bean instance (using constructor or factory method). 👉 “Object is born” — but not ready yet. 🔹 2. 𝗗𝗲𝗽𝗲𝗻𝗱𝗲𝗻𝗰𝘆 𝗜𝗻𝗷𝗲𝗰𝘁𝗶𝗼𝗻 Spring injects required dependencies (@Autowired, constructor injection, etc.) 👉 Now your bean starts gaining power ⚡ 🔹 3. 𝗔𝘄𝗮𝗿𝗲 𝗜𝗻𝘁𝗲𝗿𝗳𝗮𝗰𝗲𝘀 (Optional but powerful) Spring injects internal context via interfaces like: BeanNameAware ApplicationContextAware 👉 Your bean becomes Spring-aware 🧠 🔹 4. 𝗕𝗲𝗮𝗻 𝗣𝗼𝘀𝘁-𝗣𝗿𝗼𝗰𝗲𝘀𝘀𝗶𝗻𝗴 (Before Init) Custom logic via BeanPostProcessor 👉 Great place for custom proxies, logging, auditing 🔹 5. 𝗜𝗻𝗶𝘁𝗶𝗮𝗹𝗶𝘇𝗮𝘁𝗶𝗼𝗻 𝗣𝗵𝗮𝘀𝗲 This is where your bean becomes fully ready! Ways to initialize: @PostConstruct InitializingBean.afterPropertiesSet() Custom init-method 👉 “I’m ready to serve!” 💪 🔹 6. 𝗕𝗲𝗮𝗻 𝗣𝗼𝘀𝘁-𝗣𝗿𝗼𝗰𝗲𝘀𝘀𝗶𝗻𝗴 (After Init) Another chance to modify the bean (AOP magic happens here ✨) 🔹 7. 𝗕𝗲𝗮𝗻 𝗶𝘀 𝗥𝗲𝗮𝗱𝘆 𝘁𝗼 𝗨𝘀𝗲 Finally, your bean is in action 🎯 🔹 8. 𝗗𝗲𝘀𝘁𝗿𝘂𝗰𝘁𝗶𝗼𝗻 𝗣𝗵𝗮𝘀𝗲 When the app shuts down: @PreDestroy DisposableBean.destroy() Custom destroy-method 👉 Cleanup resources 🧹 #SpringBeansLifecycle #Java #BackendDevelopment #SpringBoot #SoftwareEngineering #SpringBootwithVC
To view or add a comment, sign in
-
-
Spent 10 minutes wondering why my Spring Boot @Scheduled task was not running. The code looked fine: @Scheduled(fixedRate = 5000) public void runTask() { System.out.println("Task running..."); } No errors. App started fine. But the task never executed. The problem: Missing @EnableScheduling on the main application class. The fix: @SpringBootApplication @EnableScheduling public class MyApplication { public static void main(String[] args) { SpringApplication_run(MyApplication.class, args); } } One annotation. That was it. Spring does not warn you when scheduling is disabled. It just silently ignores your @Scheduled methods. What scheduling issue has caught you off guard? #Java #SpringBoot #Scheduling #Debugging #BackendDevelopment
To view or add a comment, sign in
-
Your API is slow. But your code looks fine. Common Spring Boot issue: N+1 queries. 1 query for parent • N queries for children Suddenly: • More DB calls • Higher latency • Poor performance Fix: • Use JOIN FETCH • Use DTO projections • Monitor queries Spring Boot didn’t slow your app. Your data access did. #SpringBoot #Java #Performance #Backend #SystemDesign #Debugging
To view or add a comment, sign in
-
-
Your Spring Boot app was using 512MB last week. Today it's 2 GB. No errors. No crashes. Just a little slower every day. Then one morning: OutOfMemoryError Your application dies. You restart it. Everything works again. Until next week. That’s **not a fix. That’s a memory leak Something in your code is holding references to objects that should have been garbage collected. The heap keeps growing. GC runs… but nothing gets freed. Eventually, there was no space left.** Here are some **real Spring Boot memory leak culprits** 👇 JPA `Stream<Entity> is not closed EntityManager keeps every entity in memory. Load 100K rows → all stay in heap. ThreadLocal not cleared after request Filter stores the user context. Request ends. ThreadLocal stays. Memory grows with every request. ConcurrentHashMap used as cache without eviction** Data goes in. Nothing comes out. No TTL. No max size. Static List/Map that only grows `.add()` on every request. Never `.clear()`. Classic leak. How to detect it Monitor `/actuator/metrics/jvm.memory.used.` If the heap keeps growing after GC, you likely have a leak. Take a heap dump before the crash ``` jmap -dump:format=b,file=heap.hprof <pid> ``` Open in Eclipse MAT Run Leak Suspects Report → It literally shows which object is eating memory. Memory leaks don't crash your app on day one. They crash it on the day your biggest client is using it. That’s why observability is greater than restarting servers. --- If you're building Spring Boot systems, learn to debug memory leaks. It's one of the skills that separates junior developers from senior engineers. --- #SpringBoot #Java #Microservices #SoftwareEngineering #DSA #BackendDevelopment #SpringSecurity #CodingResources
To view or add a comment, sign in
-
-
Spent 15 minutes wondering why my Spring Boot @Async method was running synchronously. The code looked fine: @Async public void sendEmail(String to) { // send email logic } No errors. App started fine. But the method was blocking the main thread. The problem: Missing @EnableAsync on the main application class. The fix: @SpringBootApplication @EnableAsync public class MyApplication { public static void main(String[] args) { SpringApplication.run(MyApplication.class, args); } } One annotation. That was it. Spring does not warn you when async is disabled. It just runs your @Async methods synchronously. What async issue has caught you off guard? #Java #SpringBoot #Async #Debugging #BackendDevelopment
To view or add a comment, sign in
-
🚀 Day 17/100: Spring Boot From Zero to Production Topic: Activating Profiles in Spring Boot -> Why Activation Matters Creating profiles isn’t enough You need to activate them to use their config Otherwise, Spring Boot falls back to the default profile. -> Method 1: JVM Argument Pass this when running your app: -Dspring.profiles.active=dev Common for: Local development Switching configs quickly Loads application-dev.yaml -> Method 2: Environment Variable Set: SPRING_PROFILES_ACTIVE=dev Best for: Production environments CI/CD pipelines -> Default Behavior No active profile? default gets loaded Others are ignored Quick Insight Profiles = Config separation Activation = Making them work Simple concept. Powerful impact. This might sound simple but stay consistent. We’re building production mindset step by step. #Java #SpringBoot #SoftwareDevelopment #100DaysOfCode #Backend
To view or add a comment, sign in
-
-
Your Spring Boot app has 200 threads. Only 20 are doing real work. Here's what those 200 threads are actually doing: → 30 waiting for a DB connection. HikariCP pool = 10. 20 threads just standing in line. → 40 waiting for an external API. No read timeout set. Threads stuck in TIMED_WAITING. → 20 held by @Transactional. Method calls external service + sends email while holding a DB connection for 5+ seconds. → 10 blocked on synchronized code. One thread has the lock. 9 waiting. → 80 idle. No requests. Just consuming 1MB stack each = 80MB doing nothing. → 20 actually working. 200 threads. 20 working. 100 waiting. 80 idle. How to see this yourself: → jstack <pid> > thread-dump.txt → Or /actuator/threaddump → RUNNABLE = doing work. WAITING = stuck. BLOCKED = waiting for lock. → If WAITING > RUNNABLE — your app isn't slow because it lacks threads. It's slow because most threads are waiting. The fix: → Match HikariCP pool size to actual concurrency → Set read timeout on ALL HTTP clients → Keep @Transactional short — DB only, external calls outside → Consider Virtual Threads (Java 21) — waiting becomes cheap More threads won't fix a thread utilization problem. It'll just give you more threads doing nothing. #threads
To view or add a comment, sign in
-
🚀 Day 18/100: Spring Boot From Zero to Production Topic: Auto-Configuration 💡 What is Auto-Configuration? One of the most powerful features in Spring Boot Turns hours of setup into minutes Eliminates heavy XML configs and manual bean wiring ⏳ Before Auto-Configuration Manually define multiple beans Write hundreds of lines of XML Configure everything yourself → painful ⚙️ What Happens Now? Your @SpringBootApplication kicks things off Spring Boot scans the classpath Looks for dependencies like: spring-webmvc spring-data-jpa 👉 Presence/absence of JARs = signals 🧠 Behind the Scenes Reads a special file: META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports Contains hundreds of auto-config classes Each uses conditions like: @ConditionalOnClass @ConditionalOnMissingBean 👉 Result: Beans get configured automatically 🌐 Simple Example Add: spring-boot-starter-web Spring Boot assumes: You need a web app So it adds an embedded server (Tomcat) automatically 🛠️ Can You Override It? YES You can: Define your own beans Override defaults Disable auto-config if needed Auto-configuration isn’t magic. It’s just smart defaults + conditional logic working for you #Java #SpringBoot #SoftwareDevelopment #100DaysOfCode #Backend
To view or add a comment, sign in
-
-
Spring Boot app has 200 threads. Only 20 are doing real work. Here's what those 200 threads are actually doing: → 30 waiting for a DB connection. HikariCP pool = 10. 20 threads just standing in line. → 40 waiting for an external API. No read timeout set. Threads stuck in TIMED_WAITING. → 20 held by @Transactional. Method calls external service + sends email while holding a DB connection for 5+ seconds. → 10 blocked on synchronized code. One thread has the lock. 9 waiting. → 80 idle. No requests. Just consuming 1MB stack each = 80MB doing nothing. → 20 actually working. 200 threads. 20 working. 100 waiting. 80 idle. How to see this yourself: → jstack <pid> > thread-dump.txt → Or /actuator/threaddump → RUNNABLE = doing work. WAITING = stuck. BLOCKED = waiting for lock. → If WAITING > RUNNABLE — your app isn't slow because it lacks threads. It's slow because most threads are waiting. The fix: → Match HikariCP pool size to actual concurrency → Set read timeout on ALL HTTP clients → Keep @Transactional short — DB only, external calls outside → Consider Virtual Threads (Java 21) — waiting becomes cheap More threads won't fix a thread utilization problem. It'll just give you more threads doing nothing. #threads
To view or add a comment, sign in
-
Most beginners handle exceptions like this: try { userService.findUser(id); } catch (Exception e) { return "Something went wrong"; } Don't do this. Spring Boot gives you a cleaner way: @ControllerAdvice @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(UserNotFoundException.class) public ResponseEntity<String> handleNotFound(UserNotFoundException ex) { return ResponseEntity.status(404).body(ex.getMessage()); } @ExceptionHandler(Exception.class) public ResponseEntity<String> handleGeneral(Exception ex) { return ResponseEntity.status(500).body("Internal server error"); } } Why this is better: ✅ One place for all error handling ✅ Clean controllers — no try/catch everywhere ✅ Consistent API error responses ✅ Easy to extend as your app grows Your API consumers will thank you for returning proper HTTP status codes. #Java #SpringBoot #ExceptionHandling #BackendDevelopment #LearningInPublic
To view or add a comment, sign in
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
This one is tricky because the app starts without errors. Now I always double check my property names and use relaxed binding when working with environment variables.