Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(log): ClassNotFoundException when using Log4J2 with Spring Boot #2758

Merged
merged 2 commits into from
Sep 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions bom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@
<artifactId>hawtio-log</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.hawt</groupId>
<artifactId>hawtio-log-logback</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.hawt</groupId>
<artifactId>hawtio-log-osgi</artifactId>
Expand Down
50 changes: 50 additions & 0 deletions examples/springboot-log4j2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Hawtio Spring Boot 2 Example with Log4J2

This sample application shows how to run Hawtio with Spring Boot 2 and Log4J2.

## How to run

Run with:

mvn spring-boot:run

Hawtio is exposed at the [Actuator](https://docs.spring.io/spring-boot/docs/latest/reference/html/production-ready-endpoints.html) management port configured using
`management.server.port` in `appplication.properties`. Browse Hawtio via the following URL: http://localhost:10001/actuator/hawtio/index.html

The actual application is running on port 10000 (`server.port` in `application.properties`).

## Alternative configurations

### Alternative management endpoint base paths
If your preference is to avoid running Hawtio under the `/actuator` path, you can set the `management.endpoints.web.base-path` property in `application.properties`:

```
management.endpoints.web.base-path=/
```

Hawtio will then be available at http://localhost:10001/hawtio/index.html.

### Alternative hawtio endpoint paths

You can also customize the endpoint path of the Hawtio actuator endpoint by setting the `management.endpoints.web.path-mapping.hawtio` property in `application.properties`:

```
management.endpoints.web.path-mapping.hawtio=hawtio/console
```

### Alternative ports & context paths
Alternative ports and context path configurations can be tested by changing the following properties in `application.properties`:

```
server.port=10000
server.servlet.context-path=/sample-app
management.port=10000
management.server.servlet.context-path=/management
```

Using the above configuration, the server will use port 10000 and the custom context path `sample-app`.
The Actuator management endpoints and Hawtio will also run on port 10000 using the custom management context path `management`.
The URLs for accessing the application and Hawtio are as follows:

- Application: http://localhost:10000/sample-app/
- Hawtio: http://localhost:10000/sample-app/management/actuator/hawtio
6 changes: 6 additions & 0 deletions examples/springboot-log4j2/jmx-exporter.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
startDelaySecs: 5
ssl: false
lowercaseOutputName: true
lowercaseOutputLabelNames: true
blacklistObjectNames: ["java.lang:*"]
attrNameSnakeCase: true
217 changes: 217 additions & 0 deletions examples/springboot-log4j2/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>io.hawt</groupId>
<artifactId>project</artifactId>
<version>2.16-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>

<groupId>io.hawt.examples</groupId>
<artifactId>hawtio-example-springboot-log4j2</artifactId>
<name>${project.artifactId}</name>
<description>hawtio :: Sample Spring Boot 2.x process with Log4J2</description>
<packaging>war</packaging>

<properties>
<camel-version>3.18.1</camel-version>
</properties>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-spring-boot-dependencies</artifactId>
<version>${camel-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>io.hawt</groupId>
<artifactId>hawtio-bom</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
<!-- Spring Boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
<exclusions>
<exclusion>
<groupId>io.undertow</groupId>
<artifactId>undertow-websockets-jsr</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

<!-- hawtio -->
<dependency>
<groupId>io.hawt</groupId>
<artifactId>hawtio-springboot</artifactId>
</dependency>

<!-- Camel -->
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-stream-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-quartz-starter</artifactId>
</dependency>
<!--
This dependency is mandatory for enabling Camel management
via JMX / Hawtio.
-->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-management</artifactId>
</dependency>
<!--
To enable Camel plugin debugging feature, add this dependency.
-->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-debug</artifactId>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot-version}</version>
<configuration>
<mainClass>io.hawt.example.spring.boot.SampleSpringBootService</mainClass>
<jvmArguments>
-javaagent:./target/dependency/jmx_prometheus_javaagent.jar=10002:./jmx-exporter.yml
</jvmArguments>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>

<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>

<!-- to run with mvn hawtio:spring-boot -->
<plugin>
<groupId>io.hawt</groupId>
<artifactId>hawtio-maven-plugin</artifactId>
<version>${project.version}</version>
<configuration>
<mainClass>io.hawt.example.spring.boot.SampleSpringBootService</mainClass>
</configuration>
</plugin>

<!-- downloads the Prometheus JMX exporter java agent -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<id>copy</id>
<phase>compile</phase>
<goals>
<goal>copy</goal>
</goals>
</execution>
</executions>
<configuration>
<artifactItems>
<artifactItem>
<groupId>io.prometheus.jmx</groupId>
<artifactId>jmx_prometheus_javaagent</artifactId>
<version>0.3.1</version>
<type>jar</type>
<destFileName>jmx_prometheus_javaagent.jar</destFileName>
</artifactItem>
</artifactItems>
</configuration>
</plugin>

</plugins>
</build>
<profiles>
<profile>
<id>java11-plus</id>
<activation>
<jdk>[11,)</jdk>
</activation>
<dependencies>
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>${jaxb-version}</version>
</dependency>
<dependency>
<groupId>com.sun.activation</groupId>
<artifactId>javax.activation</artifactId>
<version>${activation-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
<version>${spring-hateoas-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.plugin</groupId>
<artifactId>spring-plugin-core</artifactId>
<version>${spring-plugin-core-version}</version>
</dependency>
</dependencies>
</profile>
</profiles>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package io.hawt.example.spring.boot;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class HelloController {

@RequestMapping("/")
@ResponseBody
public String hello() {
return "Hello World!";
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package io.hawt.example.spring.boot;

import org.apache.camel.builder.RouteBuilder;
import org.springframework.stereotype.Component;

@Component
public class SampleCamelRouter extends RouteBuilder {

@Override
public void configure() throws Exception {
// Uncomment to enable the Camel plugin Debug tab
// getContext().setDebugging(true);

from("quartz:cron?cron={{quartz.cron}}").routeId("cron")
.setBody().constant("Hello Camel! - cron")
.to("stream:out")
.to("mock:result");

from("quartz:simple?trigger.repeatInterval={{quartz.repeatInterval}}").routeId("simple")
.setBody().constant("Hello Camel! - simple")
.to("stream:out")
.to("mock:result");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package io.hawt.example.spring.boot;

import io.hawt.config.ConfigFacade;
import io.hawt.springboot.HawtioPlugin;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.actuate.trace.http.HttpTraceRepository;
import org.springframework.boot.actuate.trace.http.InMemoryHttpTraceRepository;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class SampleSpringBootService {

public static void main(String[] args) {
SpringApplication.run(SampleSpringBootService.class, args);
}

/**
* Loading an example plugin.
*/
@Bean
public HawtioPlugin samplePlugin() {
return new HawtioPlugin("sample-plugin",
"plugins",
"",
new String[] { "sample-plugin/sample-plugin.js" });
}

/**
* Set things up to be in offline mode.
*/
@Bean
public ConfigFacade configFacade() {
return ConfigFacade.getSingleton();
}

/**
* Enable HTTP tracing for Spring Boot
*/
@Bean
public HttpTraceRepository httpTraceRepository() {
return new InMemoryHttpTraceRepository();
}
}