java
179 TopicsConstrua, inove e #Hacktogether!
🛠️ Construa, inove e #Hacktogether! 🛠️ 2025 é o ano dos agentes de IA! Mas o que exatamente é um agente? E como você pode criar um? Seja você um desenvolvedor experiente ou esteja apenas começando, este hackathon virtual GRATUITO de três semanas é sua chance de mergulhar no desenvolvimento de agentes de IA. 🔥 Aprenda com mais de 20 sessões lideradas por especialistas, transmitidas ao vivo no YouTube, abordando os principais frameworks, como Semantic Kernel, Autogen, o novo Azure AI Agents SDK e o Microsoft 365 Agents SDK. 💡 Coloque a mão na massa, explore sua criatividade e crie agentes de IA poderosos! Depois, envie seu projeto e concorra a prêmios incríveis! 💸 Datas importantes: Sessões com especialistas: 8 de abril de 2025 – 30 de abril de 2025 Prazo para envio do hack: 30 de abril de 2025, 23:59 PST Não perca essa oportunidade—junte-se a nós e comece a construir o futuro da IA! 🔥 Inscrição 🎟️ Garanta sua vaga agora! Preencha o formulário para confirmar sua participação no hackathon. Em seguida, confira a programação das transmissões ao vivo e inscreva-se nas sessões que mais te interessam. Após se inscrever, apresente-se e procure por colegas de equipe! Submissão de Projetos 🚀 Leia atentamente as regras oficiais e certifique-se de entender os requisitos. Quando seu projeto estiver pronto, siga o processo de submissão. 📝 Prêmios e Categorias 🏅 Os projetos serão avaliados por um painel de jurados, incluindo engenheiros da Microsoft, gerentes de produto e defensores de desenvolvedores. Os critérios de avaliação incluirão inovação, impacto, usabilidade técnica e alinhamento com a categoria correspondente do hackathon. Cada equipe vencedora nas categorias abaixo receberá um prêmio. 💸 Melhor Agente Geral - $20,000 Melhor Agente em Python - $5,000 Melhor Agente em C# - $5,000 Melhor Agente em Java - $5,000 Melhor Agente em JavaScript/TypeScript - $5,000 Melhor Agente Copilot (usando Microsoft Copilot Studio ou Microsoft 365 Agents SDK) - $5,000 Melhor Uso do Azure AI Agent Service - $5,000 Cada equipe pode ganhar em apenas uma categoria. Todos os participantes que submeterem um projeto receberão um badge digital. Transmissões 📅 Português Inscreva-se em todas as sessões em português Dia/Horário Tópico Recursos 4/8 12:00 PM PT Bem-vindo ao AI Agents Hackathon - 4/10 12:00 PM PT Crie um aplicativo com o Azure AI Agent Service - 4/17 06:00 AM PT Seu primeiro agente de IA em JavaScript com o Azure AI Agent Service - Outros Idiomas Teremos mais de 30 transmissões em inglês, além de transmissões em espanhol e chinês. Veja a página principal para mais detalhes. 🕒 Horário de Suporte Técnico Precisa de ajuda com seu projeto? Participe do Horário de Suporte Técnico no canal de Discord de IA e receba orientação de especialistas! 🚀 Aqui estão os horários de atendimento já agendados: Dia/Horário Tópico/Anfitriões Toda quinta-feira, 12:30 PM PT Python + IA (Inglês) Toda segunda-feira, 03:00 PM PT Python + IA (Espanhol) Recursos de Aprendizado 📚 Acesse os recursos aqui! Junte-se ao TheSource EHub para explorar os principais recursos, incluindo treinamentos, transmissões ao vivo, repositórios, guias técnicos, blogs, downloads, certificações e muito mais, atualizados mensalmente. A seção de Agentes de IA oferece recursos essenciais para criar agentes de IA, enquanto outras seções fornecem insights sobre IA, ferramentas de desenvolvimento e linguagens de programação. Você também pode postar perguntas em nosso fórum de discussões ou conversar com outros participantes no canal do Discord.Meet your hosts for JDConf 2025!
JDConf 2025 is right around the corner and is set to be a global gathering for Java developers passionate about Cloud, AI, and the future of Java. With 22+ sessions and 10+ hours of live content streaming from April 9 - 10, plus additional on-demand sessions, this year’s event dives into app modernization, intelligent apps, frameworks, and AI-powered development with tools like Copilot and more. We are excited to invite you to join us with our three distinguished hosts: Bruno Borges, Sandra Ahlgrimm, and Rory Preddy. Meet Bruno Borges - Your host for JDConf 2025 Americas Bruno Borges is a seasoned professional with a rich background in the tech industry. Currently serving as Principal Product Manager at Microsoft, he focuses on Java developers' experience on Azure and beyond. With over two decades of experience, Bruno has been instrumental in bridging the gap between Java communities and Microsoft technologies and services, ensuring seamless integration, optimal developer productivity, and application performance and efficiency. His dedication to enhancing developer experiences has made him a respected figure in the Java ecosystem. Meet Sandra Ahlgrimm - Your host for JDConf 2025 EMEA Sandra Ahlgrimm is a Senior Cloud Advocate at Microsoft, specializing in Java and AI. With over fifteen years of experience as a Java developer, she is highly engaged with various communities. She co-leads the local Java User Group (JUG) and Docker Meetup. Her role on the Program Advisory Board at Oracle's GraalVM community highlights her interest in cutting-edge Java and sustainability. Meet Rory Preddy - Your host for JDConf 2025 Asia-Pacific Rory Preddy is a Principal Cloud Advocate at Microsoft, where he helps professional cloud developers discover and successfully use Microsoft’s platforms. He is a seasoned speaker whose talks are both meaningful and humorous, and he speaks around the world empowering developers to achieve more. Rory has over 25 years of experience in software development, working with various technologies such as Java, AI and Azure. Prepare for learning and some entertainment! Under the guidance of these accomplished hosts, JDConf 2025 promises to be an enlightening experience. The conference will feature a technical keynote and 22 breakout sessions, showcasing 26 Java influencers and community leaders from organizations such as Microsoft, Broadcom, Oracle, Red Hat, and IBM. Live sessions are scheduled to accommodate attendees worldwide, fostering a global networking opportunity for Java professionals and enthusiasts. With Bruno, Sandra, and Rory as your hosts, you will be entertained throughout the live stream as they invite each speaker to share more insights and learning, with Q&A after each session that attendees find very helpful. Bruno's engaging style, Sandra's enthusiasm, and Rory's humor make learning fun and interactive. Their energy and passion as hosts ensure a delightful experience for everyone. Here are few memories from last year’s event. Join the JDConf experience and earn Microsoft Rewards! We are thrilled to offer Microsoft Rewards points to participants who register or attend the JDConf! ⭐ Registration Rewards: Participants who register for one of the JDConf 2025 – America, Europe or Asia – will receive 100 Microsoft Rewards points. ⭐ Attendance Rewards: The first 300 attendees to check-in live for one of the JDConf - America, Europe or Asia - will receive 5000 Microsoft Rewards points Don't miss this chance to learn from industry leaders, connect with peers, and explore the latest developments in Java, Cloud, and AI. Join us at JDConf 2025 and be part of the future of Java development. 👉 RSVP Now at JDConf.com Learn more about our hosts: You can hear from Bruno in his recent keynote at JavaOne 2025. You can Sandra's videos here Get to know Rory's work here84Views0likes0CommentsCode the Future with Java and AI – Join Me at JDConf 2025
JDConf 2025 is just around the corner, and whether you’re a Java developer, architect, team leader, or decision maker I hope you’ll join me as we explore how Java is evolving with the power of AI and how you can start building the next generation of intelligent applications today. Why JDConf 2025? With over 22 expert-led sessions and 10+ hours of live content, JDConf is packed with learning, hands-on demos, and real-world solutions. You’ll hear from Java leaders and engineers on everything from modern application design to bringing AI into your Java stack. It’s free, virtual and your chance to connect from wherever you are. (On-demand sessions will also be available globally from April 9–10, so you can tune in anytime from anywhere.) Bring AI into Java Apps At JDConf 2025, we are going beyond buzzwords. We’ll show you how to bring AI into real Java apps, using patterns and tools that work today. First, we’ll cover Retrieval-Augmented Generation (RAG), a design pattern where your app retrieves the right business data in real time, and combines it with AI models to generate smart, context-aware responses. Whether it is answering support queries, optimizing schedules, or generating insights, RAG enables your app to think in real time. Second, we’ll introduce AI agents -- software entities that do more than respond. They act. Think about automating production line scheduling at an auto manufacturer or rebooking delayed flights for passengers. These agents interact with APIs, reason over data, and make decisions, all without human intervention. Third, we’ll explore the complete AI application platform on Azure. It is built to work with the tools Java developers already know - from Spring Boot to Quarkus - and includes OpenAI and many other models, vector search with PostgreSQL, and libraries like Spring AI and LangChain4j. Here are just two example stacks: Spring Boot AI Stack: any app hosting services like Azure Container Apps or App Service + Spring AI + OpenAI + PostgreSQL for business data and vector data store. Quarkus AI Stack: any app hosting services like Azure Container Apps or App Service + LangChain4j + OpenAI + PostgreSQL for business data and vector data store. This is how you turn existing Java apps into intelligent, interactive systems, without reinventing everything. Whether you are an experienced developer or just starting out, JDConf offers valuable opportunities to explore the latest advancements in Java, cloud, and AI technologies; gain practical insights; and connect with Java experts from across the globe – including Java 25, Virtual Threads, Spring Boot, Jakarta EE 12, AI developer experiences, Spring AI, LangChain4j, combining data and AI, automated refactoring to Java app code modernization. We’ll also show you how GitHub Copilot helps you modernize faster. GitHub Copilot's new “upgrade assistant” can help refactor your project, suggest dependency upgrades, and guide you through framework transitions, freeing you up to focus on innovation. Get the Right Fit for Your Java App And what if your apps run on JBoss, WebLogic, or Tomcat? We will walk you through how to map those apps to the right Azure service: Monoliths (JAR, WAR, EAR) → Deploy to App Service Microservices or containers → Use Azure Container Apps or AKS WebLogic & WebSphere → Lift and shift to Azure Virtual Machines JBoss EAP containers → Run on Azure Red Hat OpenShift You’ll get clear guidance on where your apps fit and how to move forward, with no guesswork or dead ends. Let's Code the Future, Together I’ll be there, along with Josh Long from the Spring AI community and Lize Raes from the LangChain4j community, delivering a technical keynote packed with practical insights. If you haven’t started building intelligent Java apps, you can start with JDConf. If you’ve already started on the journey, tune in to learn how you can enrich your experiences with the latest in tech. So, mark your calendar. Spread the word. Bring your team. JDConf 2025 is your place to build what is next with Java and AI. 👉 Register now at jdconf.com. Check out the 20+ exclusive sessions brought to you by Java experts from across the globe in all major time zones.143Views0likes0CommentsExploring Azure Container Apps for Java developers: a must-watch video series
Hi all! We are excited to share with you the second video in an ongoing series by Ayan Gupta, introducing Azure Container Apps (ACA) for Java developers. This video is titled "Java in Containers: Introduction to ACA's Architecture and Components" and is packed with valuable insights for anyone looking to take their Java applications to production. In this video, Ayan Gupta explains what ACA is and why it's an ideal platform for Java developers. You'll learn about ACA's architecture and components, and see various ways to quickly and easily deploy your Java apps using ACA. Don't miss out on this opportunity to enhance your skills and knowledge. Click here to subscribe to the Java at Microsoft YouTube channel to be notified of each new video in this series. Happy learning!63Views0likes0CommentsUnderstanding 'Always On' vs. Health Check in Azure App Service
The 'Always On' feature in Azure App Service helps keep your app warm by ensuring it remains running and responsive, even during periods of inactivity with no incoming traffic. As this feature pings to root URI after every 5 minutes. On Other hand Health-check feature helps pinging configured path every minute to monitor the application availability on each instance. What is 'Always On' in Azure App Service? The Always On feature ensures that the host process of your web app stays running continuously. This results in better responsiveness after idle periods since the app doesn’t need to cold boot when a request arrives. How to enable Always On: Navigate to the Azure Portal and open your Web App. Go to Configuration > General Settings. Toggle Always On to On. What is Health Check in Azure App Service? Health check increases your application's availability by rerouting requests away from instance where application is marked unhealthy and replacing instances if they remain unhealthy. How to enable Health-Check: Navigate to the Azure Portal and open your Web App. Under Monitoring, select Health check. Select Enable and provide a valid URL path for your application, such as /health or /api/health. Select Save. So, is it still necessary to enable the 'Always On' feature when Health Check is already pinging your application every minute? -> Yes, please find below explanation for the same. Test App scenario: Health Check enabled (pointing to /health_check path) and Always On disabled. Started the app and sent some user requests. Observations from the Test: After the application starts up, health check pings begin following the end user's request. Please find below table representing Health-check pings following user's request to root URI. Time Bucket URL Status Request Count 2025-03-20 07:00:00.0000000 / 200 6 2025-03-20 07:00:00.0000000 /health_check 200 30 2025-03-20 07:30:00.0000000 /health_check 200 30 Subsequent Health-check pings will continue, even in the absence of user requests. However, after restarting the app and in the absence of any user requests, we observed that Health Check requests were not initiated. This indicates that Health Check does not start automatically unless application is actively running and serving requests. Conclusion: Always On ensures that the app is proactively kept warm by sending root URI pings, even post-restart. The health-check feature is useful for monitoring application availability when the application is active. However, after a restart, if the application isn't active due to a lack of requests, Health-check pings won't initiate. Therefore, it is highly recommended to enable Always On, particularly for applications that need continuous availability and to avoid application process unload events. Recommendation: Enable Always On alongside Health Check to ensure optimal performance and reliability.385Views2likes0CommentsUnlock the Power of Azure Container Apps for Java Developers
Are you ready to dive into the world of Azure Container Apps and take your Java development skills to the next level? We have an exciting new video series just for you! 🎉 Check out the first video in our series, where we introduce Azure Container Apps for Java developers. This video is packed with valuable insights and practical tips to help you get started with Azure Container Apps. But that's not all! This is just the beginning. We have more videos lined up to guide you through the journey of mastering Azure Container Apps. Stay tuned for upcoming videos that will cover advanced topics and best practices. Don't miss out on updates! Subscribe to the Java at Microsoft YouTube channel to be notified of each new video as soon as it's published. Click here and hit the subscribe button to be at the forefront of Java at Microsoft. Happy coding! 🚀93Views0likes0CommentsKeep Your Azure Functions Up to Date: Identify Apps Running on Retired Versions
Running Azure Functions on retired language versions can lead to security risks, performance issues, and potential service disruptions. While Azure Functions Team notifies users about upcoming retirements through the portal, emails, and warnings, identifying affected Function Apps across multiple subscriptions can be challenging. To simplify this, we’ve provided Azure CLI scripts to help you: ✅ Identify all Function Apps using a specific runtime version ✅ Find apps running on unsupported or soon-to-be-retired versions ✅ Take proactive steps to upgrade and maintain a secure, supported environment Read on for the full set of Azure CLI scripts and instructions on how to upgrade your apps today! Why Upgrading Your Azure Functions Matters Azure Functions supports six different programming languages, with new stack versions being introduced and older ones retired regularly. Staying on a supported language version is critical to ensure: Continued access to support and security updates Avoidance of performance degradation and unexpected failures Compliance with best practices for cloud reliability Failure to upgrade can lead to security vulnerabilities, performance issues, and unsupported workloads that may eventually break. Azure's language support policy follows a structured deprecation timeline, which you can review here. How Will You Know When a Version Is Nearing its End-of-Life? The Azure Functions team communicates retirements well in advance through multiple channels: Azure Portal notifications Emails to subscription owners Warnings in client tools and Azure Portal UI when an app is running on a version that is either retired, or about to be retired in the next 6 months Official Azure Functions Supported Languages document here To help you track these changes, we recommend reviewing the language version support timelines in the Azure Functions Supported Languages document. However, identifying all affected apps across multiple subscriptions can be challenging. To simplify this process, I've built some Azure CLI scripts below that can help you list all impacted Function Apps in your environment. Linux* Function Apps with their language stack versions: az functionapp list --query "[?siteConfig.linuxFxVersion!=null && siteConfig.linuxFxVersion!=''].{Name:name, ResourceGroup:resourceGroup, OS:'Linux', LinuxFxVersion:siteConfig.linuxFxVersion}" --output table *Running on Elastic Premium and App Service Plans Linux* Function Apps on a specific language stack version: Ex: Node.js 18 az functionapp list --query "[?siteConfig.linuxFxVersion=='Node|18'].{Name:name, ResourceGroup:resourceGroup, OS: 'Linux', LinuxFxVersion:siteConfig.linuxFxVersion}" --output table *Running on Elastic Premium and App Service Plans Windows Function Apps only: az functionapp list --query "[?!contains(kind, 'linux')].{Name:name, ResourceGroup:resourceGroup, OS:'Windows'}" --output table Windows Function Apps with their language stack versions: az functionapp list --query "[?!contains(kind, 'linux')].{name: name, resourceGroup: resourceGroup}" -o json | ConvertFrom-Json | ForEach-Object { $appSettings = az functionapp config appsettings list -n $_.name -g $_.resourceGroup --query "[?name=='FUNCTIONS_WORKER_RUNTIME' || name=='WEBSITE_NODE_DEFAULT_VERSION']" -o json | ConvertFrom-Json $siteConfig = az functionapp config show -n $_.name -g $_.resourceGroup --query "{powerShellVersion: powerShellVersion, netFrameworkVersion: netFrameworkVersion, javaVersion: javaVersion}" -o json | ConvertFrom-Json $runtime = ($appSettings | Where-Object { $_.name -eq 'FUNCTIONS_WORKER_RUNTIME' }).value $version = switch($runtime) { 'node' { ($appSettings | Where-Object { $_.name -eq 'WEBSITE_NODE_DEFAULT_VERSION' }).value } 'powershell' { $siteConfig.powerShellVersion } 'dotnet' { $siteConfig.netFrameworkVersion } 'java' { $siteConfig.javaVersion } default { 'Unknown' } } [PSCustomObject]@{ Name = $_.name ResourceGroup = $_.resourceGroup OS = 'Windows' Runtime = $runtime Version = $version } } | Format-Table -AutoSize Windows Function Apps running on Node.js runtime: az functionapp list --query "[?!contains(kind, 'linux')].{name: name, resourceGroup: resourceGroup}" -o json | ConvertFrom-Json | ForEach-Object { $appSettings = az functionapp config appsettings list -n $_.name -g $_.resourceGroup --query "[?name=='FUNCTIONS_WORKER_RUNTIME' || name=='WEBSITE_NODE_DEFAULT_VERSION']" -o json | ConvertFrom-Json $runtime = ($appSettings | Where-Object { $_.name -eq 'FUNCTIONS_WORKER_RUNTIME' }).value if ($runtime -eq 'node') { $version = ($appSettings | Where-Object { $_.name -eq 'WEBSITE_NODE_DEFAULT_VERSION' }).value [PSCustomObject]@{ Name = $_.name ResourceGroup = $_.resourceGroup OS = 'Windows' Runtime = $runtime Version = $version } } } | Format-Table -AutoSize Windows Function Apps running on a specific language version: Ex: Node.js 18 az functionapp list --query "[?!contains(kind, 'linux')].{name: name, resourceGroup: resourceGroup}" -o json | ConvertFrom-Json | ForEach-Object { $appSettings = az functionapp config appsettings list -n $_.name -g $_.resourceGroup --query "[?name=='FUNCTIONS_WORKER_RUNTIME' || name=='WEBSITE_NODE_DEFAULT_VERSION']" -o json | ConvertFrom-Json $runtime = ($appSettings | Where-Object { $_.name -eq 'FUNCTIONS_WORKER_RUNTIME' }).value $nodeVersion = ($appSettings | Where-Object { $_.name -eq 'WEBSITE_NODE_DEFAULT_VERSION' }).value if ($runtime -eq 'node' -and $nodeVersion -eq '~18') { [PSCustomObject]@{ Name = $_.name ResourceGroup = $_.resourceGroup OS = 'Windows' Runtime = $runtime Version = $nodeVersion } } } | Format-Table -AutoSize All windows Apps running on unsupported language runtimes: (as of March 2025) az functionapp list --query "[?!contains(kind, 'linux')].{name: name, resourceGroup: resourceGroup}" -o json | ConvertFrom-Json | ForEach-Object { $appSettings = az functionapp config appsettings list -n $_.name -g $_.resourceGroup --query "[?name=='FUNCTIONS_WORKER_RUNTIME' || name=='WEBSITE_NODE_DEFAULT_VERSION']" -o json | ConvertFrom-Json $siteConfig = az functionapp config show -n $_.name -g $_.resourceGroup --query "{powerShellVersion: powerShellVersion, netFrameworkVersion: netFrameworkVersion}" -o json | ConvertFrom-Json $runtime = ($appSettings | Where-Object { $_.name -eq 'FUNCTIONS_WORKER_RUNTIME' }).value $version = switch($runtime) { 'node' { $nodeVer = ($appSettings | Where-Object { $_.name -eq 'WEBSITE_NODE_DEFAULT_VERSION' }).value if ([string]::IsNullOrEmpty($nodeVer)) { 'Unknown' } else { $nodeVer } } 'powershell' { $siteConfig.powerShellVersion } 'dotnet' { $siteConfig.netFrameworkVersion } default { 'Unknown' } } # Check if runtime version is unsupported $isUnsupported = switch($runtime) { 'node' { $ver = $version -replace '~','' [double]$ver -le 16 } 'powershell' { $ver = $version -replace '~','' [double]$ver -le 7.2 } 'dotnet' { $ver = $siteConfig.netFrameworkVersion $ver -notlike 'v7*' -and $ver -notlike 'v8*' } default { $false } } if ($isUnsupported) { [PSCustomObject]@{ Name = $_.name ResourceGroup = $_.resourceGroup OS = 'Windows' Runtime = $runtime Version = $version } } } | Format-Table -AutoSize Take Action Now By using these scripts, you can proactively identify and update Function Apps before they reach end-of-support status. Stay ahead of runtime retirements and ensure the reliability of your Function Apps. For step-by-step instructions to upgrade your Function Apps, check out the Azure Functions Language version upgrade guide. For more details on Azure Functions' language support lifecycle, visit the official documentation. Have any questions? Let us know in the comments below!712Views1like0CommentsObserve Quarkus Apps with Azure Application Insights using OpenTelemetry
Overview This blog shows you how to observe Red Hat Quarkus applications with Azure Application Insights using OpenTelemetry. The application is a "to do list" with a JavaScript front end and a REST endpoint. Azure Database for PostgreSQL Flexible Server provides the persistence layer for the app. The app utilizes OpenTelemetry to instrument, generate, collect, and export telemetry data for observability. The blog guides you to test your app locally, deploy it to Azure Container Apps and observe its telemetry data with Azure Application Insights. Prerequisites An Azure subscription. If you don't have an Azure subscription, create a free account before you begin. Prepare a local machine with Unix-like operating system installed - for example, Ubuntu, macOS, or Windows Subsystem for Linux. Install a Java SE implementation version 17 - for example, Microsoft build of OpenJDK. Install Maven, version 3.9.8 or higher. Install Docker for your OS. Install the Azure CLI to run Azure CLI commands. Sign in to the Azure CLI by using the az login command. To finish the authentication process, follow the steps displayed in your terminal. For other sign-in options, see Sign into Azure with Azure CLI. When you're prompted, install the Azure CLI extension on first use. For more information about extensions, see Use and manage extensions with the Azure CLI. Run az version to find the version and dependent libraries that are installed. To upgrade to the latest version, run az upgrade. This blog requires at least version 2.65.0 of Azure CLI. Prepare the Quarkus app Run the following commands to get the sample app app-insights-quarkus from GitHub: git clone https://github.com/Azure-Samples/quarkus-azure cd quarkus-azure git checkout 2024-11-27 cd app-insights-quarkus Here's the file structure of the application, with important files and directories: ├── src/main/ │ ├── java/io/quarkus/sample/ │ │ └── TodoResource.java │ └── resources/ │ ├── META-INF/resources/ │ ├── application.properties ├── pom.xml The directory src/main/resources/META-INF/resources contains the front-end code for the application. It's a Vue.js front end where you can view, add, update, and delete todo items. The src/main/java/io/quarkus/sample/TodoResource.java file implements the REST resource for the application. It uses the Jakarta REST API to expose the REST endpoints for the front end. The invocation of the REST endpoints is automatically instrumented by OpenTelemetry tracing. Besides, each REST endpoint uses the org.jboss.logging.Logger to log messages, which are collected by OpenTelemetry logging. For example, the GET method for the /api endpoint that returns all todo items is shown in the following code snippet: package io.quarkus.sample; import jakarta.inject.Inject; import jakarta.transaction.Transactional; import jakarta.validation.Valid; import jakarta.ws.rs.*; import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response.Status; import java.util.List; import org.jboss.logging.Logger; @Path("/api") public class TodoResource { private static final Logger LOG = Logger.getLogger(TodoResource.class); @Inject TodoRepository todoRepository; @GET public List<Todo> getAll() { List<Todo> todos = todoRepository.findAll(); LOG.info("Found " + todos.size() + " todos"); return todos; } } The pom.xml file contains the project configuration, including the dependencies for the Quarkus application. The application uses the following extensions to support OpenTelemetry: <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-opentelemetry</artifactId> </dependency> <dependency> <groupId>io.opentelemetry.instrumentation</groupId> <artifactId>opentelemetry-jdbc</artifactId> </dependency> <dependency> <groupId>io.opentelemetry</groupId> <artifactId>opentelemetry-exporter-logging</artifactId> </dependency> The src/main/resources/application.properties file contains the configuration for the Quarkus application. The configuration includes database connection properties for production, such as the JDBC URL and username. The configuration also includes the OpenTelemetry properties, such as enabling OpenTelemetry including logs and JDBC instrumentation at build time, using logging as exporter in development mode, and specifying the endpoint for the OpenTelemetry Protocol (OTLP) exporter in production mode. The following example shows the configuration for the OpenTelemetry: quarkus.otel.enabled=true quarkus.otel.logs.enabled=true quarkus.datasource.jdbc.telemetry=true %dev.quarkus.otel.logs.exporter=logging %dev.quarkus.otel.traces.exporter=logging %prod.quarkus.otel.exporter.otlp.endpoint=${OTEL_EXPORTER_OTLP_ENDPOINT} Run the Quarkus app locally Quarkus supports the automatic provisioning of unconfigured services in development mode. For more information, see Dev Services Overview in the Quarkus documentation. Now, run the following command to enter Quarkus dev mode, which automatically provisions a PostgreSQL database as a Docker container for the app: mvn clean package quarkus:dev The output should look like the following example: 2025-03-17 11:14:32,880 INFO [io.qua.dat.dep.dev.DevServicesDatasourceProcessor] (build-26) Dev Services for default datasource (postgresql) started - container ID is 56acc7e1cb46 2025-03-17 11:14:32,884 INFO [io.qua.hib.orm.dep.dev.HibernateOrmDevServicesProcessor] (build-4) Setting quarkus.hibernate-orm.database.generation=drop-and-create to initialize Dev Services managed database __ ____ __ _____ ___ __ ____ ______ --/ __ \/ / / / _ | / _ \/ //_/ / / / __/ -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \ --\___\_\____/_/ |_/_/|_/_/|_|\____/___/ 2025-03-17 11:14:36,202 INFO [io.ope.exp.log.LoggingSpanExporter] (JPA Startup Thread) 'quarkus' : 80437b598962f82bffd0735bbf00e9f1 aa86f0553056a8c9 CLIENT [tracer: io.opentelemetry.jdbc:2.8.0-alpha] AttributesMap{data={db.name=quarkus, server.port=59406, server.address=localhost, db.connection_string=postgresql://localhost:59406, db.statement=set client_min_messages = WARNING, db.system=postgresql}, capacity=128, totalAddedValues=6} 1970-01-01T00:00:00Z INFO ''quarkus' : 80437b598962f82bffd0735bbf00e9f1 aa86f0553056a8c9 CLIENT [tracer: io.opentelemetry.jdbc:2.8.0-alpha] AttributesMap{data={db.name=quarkus, server.port=59406, server.address=localhost, db.connection_string=postgresql://localhost:59406, db.statement=set client_min_messages = WARNING, db.system=postgresql}, capacity=128, totalAddedValues=6}' : 00000000000000000000000000000000 0000000000000000 [scopeInfo: io.quarkus.opentelemetry:] {code.lineno=-1, log.logger.namespace="org.jboss.logmanager.Logger", thread.id=122, thread.name="JPA Startup Thread"} 2025-03-17 11:14:36,236 INFO [io.ope.exp.log.LoggingSpanExporter] (JPA Startup Thread) 'DROP table quarkus' : 6b732661c29a9f0966403d49db9e4cff d86f29284f0d8eac CLIENT [tracer: io.opentelemetry.jdbc:2.8.0-alpha] AttributesMap{data={db.operation=DROP table, db.name=quarkus, server.port=59406, server.address=localhost, db.connection_string=postgresql://localhost:59406, db.statement=drop table if exists Todo cascade, db.system=postgresql}, capacity=128, totalAddedValues=7} 1970-01-01T00:00:00Z INFO ''DROP table quarkus' : 6b732661c29a9f0966403d49db9e4cff d86f29284f0d8eac CLIENT [tracer: io.opentelemetry.jdbc:2.8.0-alpha] AttributesMap{data={db.operation=DROP table, db.name=quarkus, server.port=59406, server.address=localhost, db.connection_string=postgresql://localhost:59406, db.statement=drop table if exists Todo cascade, db.system=postgresql}, capacity=128, totalAddedValues=7}' : 00000000000000000000000000000000 0000000000000000 [scopeInfo: io.quarkus.opentelemetry:] {code.lineno=-1, log.logger.namespace="org.jboss.logmanager.Logger", thread.id=122, thread.name="JPA Startup Thread"} 2025-03-17 11:14:36,259 INFO [io.ope.exp.log.LoggingSpanExporter] (JPA Startup Thread) 'CREATE table quarkus' : 54df3edf9f523a71bc85d0106a57016c bb43aa63ec3526ed CLIENT [tracer: io.opentelemetry.jdbc:2.8.0-alpha] AttributesMap{data={db.operation=CREATE table, db.name=quarkus, server.port=59406, server.address=localhost, db.connection_string=postgresql://localhost:59406, db.statement=create table Todo (completed boolean not null, ordering integer, id bigint generated by default as identity, title varchar(?) unique, url varchar(?), primary key (id)), db.system=postgresql}, capacity=128, totalAddedValues=7} 1970-01-01T00:00:00Z INFO ''CREATE table quarkus' : 54df3edf9f523a71bc85d0106a57016c bb43aa63ec3526ed CLIENT [tracer: io.opentelemetry.jdbc:2.8.0-alpha] AttributesMap{data={db.operation=CREATE table, db.name=quarkus, server.port=59406, server.address=localhost, db.connection_string=postgresql://localhost:59406, db.statement=create table Todo (completed boolean not null, ordering integer, id bigint generated by default as identity, title varchar(?) unique, url varchar(?), primary key (id)), db.system=postgresql}, capacity=128, totalAddedValues=7}' : 00000000000000000000000000000000 0000000000000000 [scopeInfo: io.quarkus.opentelemetry:] {code.lineno=-1, log.logger.namespace="org.jboss.logmanager.Logger", thread.id=122, thread.name="JPA Startup Thread"} 2025-03-17 11:14:36,438 INFO [io.quarkus] (Quarkus Main Thread) quarkus-todo-demo-app-insights 1.0.0-SNAPSHOT on JVM (powered by Quarkus 3.16.3) started in 7.409s. Listening on: http://localhost:8080 1970-01-01T00:00:00Z INFO 'quarkus-todo-demo-app-insights 1.0.0-SNAPSHOT on JVM (powered by Quarkus 3.16.3) started in 7.409s. Listening on: http://localhost:8080' : 00000000000000000000000000000000 0000000000000000 [scopeInfo: io.quarkus.opentelemetry:] {code.function="printStartupTime", code.lineno=109, code.namespace="io.quarkus.bootstrap.runner.Timing", log.logger.namespace="org.jboss.logging.Logger", thread.id=112, thread.name="Quarkus Main Thread"} 2025-03-17 11:14:36,441 INFO [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated. 1970-01-01T00:00:00Z INFO 'Profile dev activated. Live Coding activated.' : 00000000000000000000000000000000 0000000000000000 [scopeInfo: io.quarkus.opentelemetry:] {code.function="printStartupTime", code.lineno=113, code.namespace="io.quarkus.bootstrap.runner.Timing", log.logger.namespace="org.jboss.logging.Logger", thread.id=112, thread.name="Quarkus Main Thread"} 2025-03-17 11:14:36,443 INFO [io.quarkus] (Quarkus Main Thread) Installed features: [agroal, cdi, hibernate-orm, hibernate-validator, jdbc-postgresql, narayana-jta, opentelemetry, rest, rest-jackson, smallrye-context-propagation, vertx] 1970-01-01T00:00:00Z INFO 'Installed features: [agroal, cdi, hibernate-orm, hibernate-validator, jdbc-postgresql, narayana-jta, opentelemetry, rest, rest-jackson, smallrye-context-propagation, vertx]' : 00000000000000000000000000000000 0000000000000000 [scopeInfo: io.quarkus.opentelemetry:] {code.function="printStartupTime", code.lineno=115, code.namespace="io.quarkus.bootstrap.runner.Timing", log.logger.namespace="org.jboss.logging.Logger", thread.id=112, thread.name="Quarkus Main Thread"} -- Tests paused Press [e] to edit command line args (currently ''), [r] to resume testing, [o] Toggle test output, [:] for the terminal, [h] for more options> The output shows that the Quarkus app is running in development mode. The app is listening on http://localhost:8080. The PostgreSQL database is automatically provisioned as a Docker container for the app. The OpenTelemetry instrumentation for Quarkus and JDBC is enabled, and the telemetry data is exported to the console. Access the application GUI at http://localhost:8080. You should see a similar Todo app with an empty todo list, as shown in the following screenshot: Switch back to the terminal where Quarkus dev mode is running, you should see more OpenTelemetry data exported to the console. For example, the following output shows the OpenTelemetry logging and tracing data for the GET method for the /api endpoint: 2025-03-17 11:15:13,785 INFO [io.qua.sam.TodoResource] (executor-thread-1) Found 0 todos 1970-01-01T00:00:00Z INFO 'Found 0 todos' : 7cf260232ff81caf90abc354357c16ab c48a4a02e74e1901 [scopeInfo: io.quarkus.opentelemetry:] {code.function="getAll", code.lineno=25, code.namespace="io.quarkus.sample.TodoResource", log.logger.namespace="org.jboss.logging.Logger", parentId="c48a4a02e74e1901", thread.id=116, thread.name="executor-thread-1"} 2025-03-17 11:15:13,802 INFO [io.ope.exp.log.LoggingSpanExporter] (vert.x-eventloop-thread-1) 'GET /api' : 7cf260232ff81caf90abc354357c16ab c48a4a02e74e1901 SERVER [tracer: io.quarkus.opentelemetry:] AttributesMap{data={http.response.status_code=200, url.scheme=http, server.port=8080, server.address=localhost, client.address=0:0:0:0:0:0:0:1, user_agent.original=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36 Edg/134.0.0.0, url.path=/api/, code.namespace=io.quarkus.sample.TodoResource, http.request.method=GET, code.function=getAll, http.response.body.size=2, http.route=/api}, capacity=128, totalAddedValues=12} 1970-01-01T00:00:00Z INFO ''GET /api' : 7cf260232ff81caf90abc354357c16ab c48a4a02e74e1901 SERVER [tracer: io.quarkus.opentelemetry:] AttributesMap{data={http.response.status_code=200, url.scheme=http, server.port=8080, server.address=localhost, client.address=0:0:0:0:0:0:0:1, user_agent.original=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36 Edg/134.0.0.0, url.path=/api/, code.namespace=io.quarkus.sample.TodoResource, http.request.method=GET, code.function=getAll, http.response.body.size=2, http.route=/api}, capacity=128, totalAddedValues=12}' : 00000000000000000000000000000000 0000000000000000 [scopeInfo: io.quarkus.opentelemetry:] {code.function="export", code.lineno=65, code.namespace="io.opentelemetry.exporter.logging.LoggingSpanExporter", log.logger.namespace="org.jboss.logmanager.Logger", thread.id=126, thread.name="vert.x-eventloop-thread-1"} Then return to the web browser and interact with the Todo app, try to add a new todo item by typing in the text box and pressing ENTER, selecting the checkbox to mark the todo item as completed, or selecting Clear completed to remove all completed todo items. You can also delete a todo item by selecting the x icon when you hover over it. The app should work as expected. Finally, switch back to the terminal and press q to exit Quarkus dev mode. Create the Azure resources The steps in this section show you how to create the following Azure resources to run the Quarkus sample app on Azure: Azure Database for PostgreSQL Flexible Server Azure Container Registry Azure Container Apps environment Azure Application Insights First, define the following variables in your bash shell by replacing the placeholders with your own values. They will be used throughout the example: UNIQUE_VALUE=<your unique value> LOCATION=eastus2 RESOURCE_GROUP_NAME=${UNIQUE_VALUE}rg DB_SERVER_NAME=${UNIQUE_VALUE}db DB_NAME=demodb REGISTRY_NAME=${UNIQUE_VALUE}reg ACA_ENV=${UNIQUE_VALUE}env APP_INSIGHTS=${UNIQUE_VALUE}appinsights ACA_NAME=${UNIQUE_VALUE}aca Next, create the resource group to host Azure resources: az group create \ --name $RESOURCE_GROUP_NAME \ --location $LOCATION Then, create the Azure resources in the resource group by following the steps below. Create an Azure Database for PostgreSQL flexible server instance: az postgres flexible-server create \ --name $DB_SERVER_NAME \ --resource-group $RESOURCE_GROUP_NAME \ --database-name $DB_NAME \ --public-access None \ --sku-name Standard_B1ms \ --tier Burstable \ --active-directory-auth Enabled Create the Azure Container Registry and get the login server: az acr create \ --resource-group $RESOURCE_GROUP_NAME \ --location ${LOCATION} \ --name $REGISTRY_NAME \ --sku Basic LOGIN_SERVER=$(az acr show \ --name $REGISTRY_NAME \ --query 'loginServer' \ --output tsv) Create the Azure Container Apps environment: az containerapp env create \ --resource-group $RESOURCE_GROUP_NAME \ --location $LOCATION \ --name $ACA_ENV Create an Azure Application Insights instance: logAnalyticsWorkspace=$(az monitor log-analytics workspace list \ -g $RESOURCE_GROUP_NAME \ --query "[0].name" -o tsv | tr -d '\r') az monitor app-insights component create \ --resource-group $RESOURCE_GROUP_NAME \ --location $LOCATION \ --app $APP_INSIGHTS \ --workspace $logAnalyticsWorkspace Use the created Application Insights instance as the destination service to enable the managed OpenTelemetry agent for the Azure Container Apps environment: appInsightsConn=$(az monitor app-insights component show \ --app $APP_INSIGHTS \ -g $RESOURCE_GROUP_NAME \ --query 'connectionString' -o tsv | tr -d '\r') az containerapp env telemetry app-insights set \ --name $ACA_ENV \ --resource-group $RESOURCE_GROUP_NAME \ --connection-string $appInsightsConn \ --enable-open-telemetry-logs true \ --enable-open-telemetry-traces true When you deploy the Quarkus app to the Azure Container Apps environment later in this blog, the OpenTelemetry data is automatically collected by the managed OpenTelemetry agent and exported to the Application Insights instance. Deploy the Quarkus app to Azure Container Apps You have set up all the necessary Azure resources to run the Quarkus app on Azure Container Apps. In this section, you containerize the Quarkus app and deploy it to Azure Container Apps. First, use the following command to build the application. This command uses the Jib extension to build the container image. Quarkus instrumentation works both in JVM and native modes. In this blog, you build the container image for JVM mode, to work with Microsoft Entra ID authentication for Azure Database for PostgreSQL flexible server. TODO_QUARKUS_IMAGE_NAME=todo-quarkus-app-insights TODO_QUARKUS_IMAGE_TAG=${LOGIN_SERVER}/${TODO_QUARKUS_IMAGE_NAME}:1.0 mvn clean package -Dquarkus.container-image.build=true -Dquarkus.container-image.image=${TODO_QUARKUS_IMAGE_TAG} Next, sign in to the Azure Container Registry and push the Docker image to the registry: az acr login --name $REGISTRY_NAME docker push $TODO_QUARKUS_IMAGE_TAG Then, use the following command to create a Container Apps instance to run the app after pulling the image from the Container Registry: az containerapp create \ --resource-group $RESOURCE_GROUP_NAME \ --name $ACA_NAME \ --image $TODO_QUARKUS_IMAGE_TAG \ --environment $ACA_ENV \ --registry-server $LOGIN_SERVER \ --registry-identity system \ --target-port 8080 \ --ingress 'external' \ --min-replicas 1 Finally, connect the Azure Database for PostgreSQL Flexible Server instance to the container app using Service Connector: # Install the Service Connector passwordless extension az extension add --name serviceconnector-passwordless --upgrade --allow-preview true az containerapp connection create postgres-flexible \ --resource-group $RESOURCE_GROUP_NAME \ --name $ACA_NAME \ --target-resource-group $RESOURCE_GROUP_NAME \ --server $DB_SERVER_NAME \ --database $DB_NAME \ --system-identity \ --container $ACA_NAME \ --yes Wait for a while until the application is deployed, started and running. Then get the application URL and open it in a browser: QUARKUS_URL=https://$(az containerapp show \ --resource-group $RESOURCE_GROUP_NAME \ --name $ACA_NAME \ --query properties.configuration.ingress.fqdn -o tsv) echo $QUARKUS_URL You should see the similar Todo app when you ran the app locally before. Interact with the app by adding, completing and removing todo items, which generates telemetry data and sends it to Azure Application Insights. Observe the Quarkus app with Azure Application Insights Open the Azure Portal and navigate to the Azure Monitor Application Insights resource you created earlier. You can monitor the application with different views backed by the telemetry data sent from the application. For example: Investigate > Application map: Shows the application components and their dependencies. Investigate > Failures: Shows the failures and exceptions in the application. Investigate > Performance: Shows the performance of the application. Monitoring > Logs: Shows the logs and traces of the application. You may notice that metrics are not observed in the Application Insights in this blog, that's because the Application Insights endpoint used in the managed OpenTelemetry agent doesn't accept metrics yet, which is listed as a known limitation. This is also the reason why Quarkus metrics is not enabled in the configuration file with quarkus.otel.metrics.enabled=true above. Alternatively, you can consider using Quarkus Opentelemetry Exporter for Microsoft Azure in your Quarkus apps to export the telemetry data directly to Azure Application Insights. Clean up resources To avoid Azure charges, you should clean up unneeded resources. When the resources are no longer needed, use the az group delete command to remove the resource group and all Azure resources within it: az group delete \ --name $RESOURCE_GROUP_NAME \ --yes \ --no-wait Next steps In this blog, you observe the Quarkus app with Azure Application Insights using OpenTelemetry. To learn more, explore the following resources: OpenTelemetry on Azure Collect and read OpenTelemetry data in Azure Container Apps (preview) Application Insights overview Using OpenTelemetry Deploy a Java application with Quarkus on an Azure Container Apps Secure Quarkus applications with Microsoft Entra ID using OpenID Connect Deploy a Java application with Quarkus on an Azure Kubernetes Service cluster Deploy serverless Java apps with Quarkus on Azure Functions Jakarta EE on Azure320Views1like0CommentsGetting Started with Java WebJobs on Azure App Service
Getting Started with Linux WebJobs on App Service - Java WebJobs Intro WebJobs is a feature of Azure App Service that enables you to run a program or script in the same instance as a web app. All app service plans support WebJobs. There's no extra cost to use WebJobs. This sample uses a Triggered (scheduled) WebJob to output the system time once every 15 minutes. Create Web App Before creating our WebJobs, we need to create an App Service webapp. If you already have an App Service Web App, skip to the next step Otherwise, in the portal, select App Services > Create > Web App. After following the create instructions and selecting one of the Java runtime stacks, create your App Service Web App. The stack must be Java, since we plan on writing our WebJob using Java and a bash startup script. Next, we’ll add a basic WebJob to our app. Create WebJob Before we do anything else, let’s write our WebJob. This will execute every time our WebJob is triggered. WebJobs on App Service can be run on a Triggered (Scheduled) basis or Continuously. This example uses a Triggered WebJob. For this example, we’ll need to compress two files into a zip archive that we’ll upload to our App Service Web App. We’ll need a startup script and an executable jar. The full code for this sample is available at: https://github.com/Azure-Samples/App-Service-Java-WebJobs-QuickStart Digging into the code, our Java project located at project/src/main/java/webjob/HelloWorld.java is relatively simple. It just outputs a message & the current time to the console. import java.time.LocalDateTime; public class HelloWorld { public static void main(String[] args) { System.out.println("------------------------------------------------------------"); System.out.println("Hello World from WebJob: " + LocalDateTime.now()); System.out.println("------------------------------------------------------------"); } } The run.sh script located at the root of our git repo, just runs a jar with the name that we’ve set in our maven configuration. This script will run when our WebJob is triggered, and it is the job of this script to kick off our Java executable (jar). java -jar webjob-artifact-1.0.0.jar Now we need to compile our Java project to produce the executable jar. There are multiple ways to do this, but for this example, we’ll use Maven. Run the following commands from the project/ directory: mvn install mvn package After successfully building our app with mvn package, our jar file will be located at project/target/webjob-artifact-1.0.0.jar. Now we have everything we need to assemble our zip file. Again, there are multiple ways to do this, but for this demo we’ll use the zip CLI utility to create our zip file called webjob.zip. First move your jar file to the root of the git repo with project/target/webjob-artifact-1.0.0.jar. Then run the zip command to package our application as a zip file. zip webjob.zip run.sh webjob-artifact-1.0.0.jar Now it’s time to create our WebJob and upload our zip file. Create WebJob in Portal Start by entering your Web App overview page. Then, under Settings select WebJobs. Here we can create and manage our App Service WebJobs for this Web App. Click Add to create a new WebJob. Now we can name our WebJob, upload our zip from the previous step, and choose our execution type. Under Type, select Triggered. Under CRON Expression, enter the following to trigger our WebJob once every 15 minutes. 0 */15 * * * * Note: These are NCRONTAB expressions, not standard Linux CRONTAB expressions. An important distinction. Now click Create WebJob to finish making our new WebJob. Let’s test it out now. Run Manually or Scheduled To manually test our WebJob, we can click the play button under Run. A status of Completed means that WebJob is finished. Confirm Results in Logs We can check the logs to confirm that the console print statements from our Java file were output to the console. While this is a basic example, WebJobs are a powerful and easy to use feature that have incredible utility for running scheduled (or continuous) actions in conjunction with your App Service Web Apps at no additional cost. Learn more about WebJobs on App Service95Views0likes0Comments