简体   繁体   中英

Spring Boot JMX ClassNotFoundException

I have some in-memory storage I'd like to expose via JMX to monitor:

@Component
@CompileStatic
@ManagedResource(
    objectName = 'bean:name=PageFragmentRepository',
    currencyTimeLimit = 15
)

class EmbeddedPageFragmentRepository implements PageFragmentRepository {

    private final Map<String, Map<String, PageFragment>> storage = new ConcurrentHashMap<>()

    @ManagedOperation(description = 'All fragments')
    @Override
    List<PageFragment> findAll() {
        return storage.values().stream().flatMap { it.values() }.collect(toList())
    }
}

I can see the bean on jconsole , but then I try to call the operation when the storage is non-empty, I get:

ClassNotFoundException: c.i.w.g.p.f.e.PageFragment

This is my class, so I tried configuring the classpath when calling jconsole :

jconsole -J-Djava.class.path=$JAVA_HOME/lib/jconsole.jar:$JAVA_HOME/lib/tools.jar:/path/to/my/boot/app.jar 2345

This results in ClassNotFound: GroovyObject (yes, I'm using Groovy). This means that despite I added the Spring Boot JAR to the classpath, still all the classes from dependant libraries packaged into it are not visible.

Any ideas what am I doing wrong? How can I see the result of the operation without ClassNotFoundException s?

If PageFragment is within the module that generated app.jar I don't see why it wouldn't work; If it doesn't, it's placed in a lib of the fat jar and there is no chance for JConsole to find it there.

That being said, all that does not really matter. I wouldn't return any complex object such as that PageFragment of yours with JMX. JConsole has no way to handle custom objects in the UI anyway so you'll get no benefit from calling that method there.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM