arthas
arthas copied to clipboard
Enhance error! exception: java.lang.NoClassDefFoundError: class names don't match
- [x] 我已经在 issues 里搜索,没有重复的issue。
环境信息
- Arthas 版本: 3.3.3
- 操作系统版本: macos 10.15.5
- 目标进程的JVM版本: 1.8.0_212
java version "1.8.0_212" Java(TM) SE Runtime Environment (build 1.8.0_212-b10) Java HotSpot(TM) 64-Bit Server VM (build 25.212-b10, mixed mode)
- 执行
arthas-boot
的方式:java -jar arthas-boot.jar
重现问题的步骤
- 启动demo程序(基于Springboo的web应用,jar方式启动)
- 启动arthas:
java -jar arthas-boot.jar
- 执行jad命令能正常反编译代码:
jad --source-only com.faceless.springbootdemo.web.controller.BookController
- 执行watch命令(确认包和类名无误):
watch com.faceless.springbootdemo.web.controller.BookController findBook "{params,returnObj}" -x 2
提示无法enhance的异常。
期望的结果
显示正常watch结果。
实际运行的结果
watch
命令无法得到正常监控结果。提示无法enhance的异常:
[arthas@40827]$ watch com.faceless.springbootdemo.web.controller.BookController findBook "{params,returnObj}" -x 2
Affect(class count: 1 , method count: 1) cost in 31 ms, listenerId: 9
Enhance error! exception: java.lang.NoClassDefFoundError: class names don't match, check arthas log: /Users/weiping/logs/arthas/arthas.log
arthas.log对应的日志为:
2020-06-19 20:51:31 [as-command-execute-daemon] INFO c.t.arthas.core.advisor.Enhancer -enhance matched classes: [class com.faceless.springbootdemo.web.controller.BookController]
2020-06-19 20:51:31 [as-command-execute-daemon] ERROR c.t.arthas.core.advisor.Enhancer -Enhancer error, matchingClasses: [class com.faceless.springbootdemo.web.controller.BookController]
java.lang.NoClassDefFoundError: class names don't match
at sun.instrument.InstrumentationImpl.retransformClasses0(Native Method)
at sun.instrument.InstrumentationImpl.retransformClasses(InstrumentationImpl.java:144)
at com.taobao.arthas.core.advisor.Enhancer.enhance(Enhancer.java:366)
at com.taobao.arthas.core.command.monitor200.EnhancerCommand.enhance(EnhancerCommand.java:135)
at com.taobao.arthas.core.command.monitor200.EnhancerCommand.process(EnhancerCommand.java:87)
at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl.process(AnnotatedCommandImpl.java:82)
at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl.access$100(AnnotatedCommandImpl.java:18)
at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl$ProcessHandler.handle(AnnotatedCommandImpl.java:111)
at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl$ProcessHandler.handle(AnnotatedCommandImpl.java:108)
at com.taobao.arthas.core.shell.system.impl.ProcessImpl$CommandProcessTask.run(ProcessImpl.java:372)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
附:测试类BookController的代码:
package com.faceless.springbootdemo.web.controller;
@RestController
@RequestMapping("/api/v1")
@Slf4j
public class BookController {
@Autowired
private BookDao bookDao;
@GetMapping(value="/book/{id}")
public Result findBook(@PathVariable("id") Integer id) {
Optional<Book> bookOptional = bookDao.findOne(id);
if (bookOptional.isPresent()) {
log.debug("Found the book: {}", bookOptional.get().toString());
return Result.succ(bookOptional.get());
} else {
return Result.fail("Book NOT found. id=" + id);
}
}
}
可以提交一个可运行的 demo不?能重现比较好排查
我也有这个问题,你是怎么解决的?
我也有这个问题,你是怎么解决的?
可以提供一个可执行demo不?
遇到了相同的问题,jad反编译时方法里面有错误提示:
/*
* Exception decompiling
*/
@Override
@Metrics(logInput=true)
public Result queryMain(SearchMainParams mainParams) {
/*
* This method has failed to decompile. When submitting a bug report, please provide this stack trace, and (if you hold appropriate legal rights) the relevant class file.
* org.benf.cfr.reader.util.ConfusedCFRException: Tried to end blocks [0[TRYBLOCK]], but top level block is 13[CATCHBLOCK]
* org.benf.cfr.reader.bytecode.analysis.opgraph.Op04StructuredStatement.processEndingBlocks(Op04StructuredStatement.java:429)
* org.benf.cfr.reader.bytecode.analysis.opgraph.Op04StructuredStatement.buildNestedBlocks(Op04StructuredStatement.java:478)
* org.benf.cfr.reader.bytecode.analysis.opgraph.Op03SimpleStatement.createInitialStructuredBlock(Op03SimpleStatement.java:728)
* org.benf.cfr.reader.bytecode.CodeAnalyser.getAnalysisInner(CodeAnalyser.java:806)
* org.benf.cfr.reader.bytecode.CodeAnalyser.getAnalysisOrWrapFail(CodeAnalyser.java:258)
* org.benf.cfr.reader.bytecode.CodeAnalyser.getAnalysis(CodeAnalyser.java:192)
* org.benf.cfr.reader.entities.attributes.AttributeCode.analyse(AttributeCode.java:94)
* org.benf.cfr.reader.entities.Method.analyse(Method.java:521)
* org.benf.cfr.reader.entities.ClassFile.analyseMid(ClassFile.java:1035)
* org.benf.cfr.reader.entities.ClassFile.analyseTop(ClassFile.java:922)
* org.benf.cfr.reader.Driver.doClass(Driver.java:83)
* org.benf.cfr.reader.CfrDriverImpl.analyse(CfrDriverImpl.java:67)
* com.taobao.arthas.core.util.Decompiler.decompile(Decompiler.java:68)
* com.taobao.arthas.core.command.klass100.JadCommand.processExactMatch(JadCommand.java:171)
* com.taobao.arthas.core.command.klass100.JadCommand.process(JadCommand.java:147)
* com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl.process(AnnotatedCommandImpl.java:82)
* com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl.access$100(AnnotatedCommandImpl.java:18)
* com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl$ProcessHandler.handle(AnnotatedCommandImpl.java:111)
* com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl$ProcessHandler.handle(AnnotatedCommandImpl.java:108)
* com.taobao.arthas.core.shell.system.impl.ProcessImpl$CommandProcessTask.run(ProcessImpl.java:385)
* java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
* java.util.concurrent.FutureTask.run(FutureTask.java:266)
* java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
* java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
* java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
* java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
* java.lang.Thread.run(Thread.java:748)
*/
throw new IllegalStateException(Decompilation failed);
}
同样的问题, jad能反编译,但是watch和trace都报错Enhance error! exception: java.lang.NoClassDefFoundError: class names don't match
同样的问题, jad能反编译,但是watch和trace都报错Enhance error! exception: java.lang.NoClassDefFoundError: class names don't match
@lp8608 提交一个可重现的demo
我也遇到了这个问题
[arthas@1]$ trace org.springframework.cloud.gateway.filter.GlobalFilter filter '#cost > 50' Affect(class count: 3 , method count: 3) cost in 1702 ms, listenerId: 1 Enhance error! exception: java.lang.ClassFormatError error happens when enhancing class: null, check arthas log: /root/logs/arthas/arthas.log
我也遇到了这个问题
[arthas@1]$ trace org.springframework.cloud.gateway.filter.GlobalFilter filter '#cost > 50' Affect(class count: 3 , method count: 3) cost in 1702 ms, listenerId: 1 Enhance error! exception: java.lang.ClassFormatError error happens when enhancing class: null, check arthas log: /root/logs/arthas/arthas.log
https://github.com/alibaba/arthas/search?q=ClassFormatError&type=issues
我也遇到了这个问题 [arthas@1]$ trace org.springframework.cloud.gateway.filter.GlobalFilter filter '#cost > 50' Affect(class count: 3 , method count: 3) cost in 1702 ms, listenerId: 1 Enhance error! exception: java.lang.ClassFormatError error happens when enhancing class: null, check arthas log: /root/logs/arthas/arthas.log
https://github.com/alibaba/arthas/search?q=ClassFormatError&type=issues
例子来了:
-- 报错信息
[arthas@1]$ trace org.springframework.cloud.gateway.filter.NettyRoutingFilter filter '#cost>50'
Affect(class count: 1 , method count: 1) cost in 29 ms, listenerId: 6
Enhance error! exception: java.lang.ClassFormatError
error happens when enhancing class: null, check arthas log: /root/logs/arthas/arthas.log
-- arthas.log 日志文件内容
2021-02-28 15:01:01 [arthas-command-execute] INFO c.t.arthas.core.advisor.Enhancer -enhance matched classes: [class org.springframework.cloud.gateway.filter.NettyRoutingFilter]
2021-02-28 15:01:01 [arthas-command-execute] ERROR c.t.arthas.core.advisor.Enhancer -Enhancer error, matchingClasses: [class org.springframework.cloud.gateway.filter.NettyRoutingFilter]
java.lang.ClassFormatError: null
at sun.instrument.InstrumentationImpl.retransformClasses0(Native Method)
at sun.instrument.InstrumentationImpl.retransformClasses(InstrumentationImpl.java:144)
at com.taobao.arthas.core.advisor.Enhancer.enhance(Enhancer.java:396)
at com.taobao.arthas.core.command.monitor200.EnhancerCommand.enhance(EnhancerCommand.java:163)
at com.taobao.arthas.core.command.monitor200.EnhancerCommand.process(EnhancerCommand.java:110)
at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl.process(AnnotatedCommandImpl.java:82)
at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl.access$100(AnnotatedCommandImpl.java:18)
at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl$ProcessHandler.handle(AnnotatedCommandImpl.java:111)
at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl$ProcessHandler.handle(AnnotatedCommandImpl.java:108)
at com.taobao.arthas.core.shell.system.impl.ProcessImpl$CommandProcessTask.run(ProcessImpl.java:385)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
--被增强的类 Spring Cloud Gateway 2.1.2-RELEASE版本
package org.springframework.cloud.gateway.filter;
import java.net.URI;
import java.util.List;
import io.netty.handler.codec.http.DefaultHttpHeaders;
import io.netty.handler.codec.http.HttpMethod;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.netty.NettyPipeline;
import reactor.netty.http.client.HttpClient;
import reactor.netty.http.client.HttpClientResponse;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.cloud.gateway.config.HttpClientProperties;
import org.springframework.cloud.gateway.filter.headers.HttpHeadersFilter;
import org.springframework.cloud.gateway.filter.headers.HttpHeadersFilter.Type;
import org.springframework.cloud.gateway.support.TimeoutException;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.NettyDataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.AbstractServerHttpResponse;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.server.ServerWebExchange;
import static org.springframework.cloud.gateway.filter.headers.HttpHeadersFilter.filterRequest;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.CLIENT_RESPONSE_CONN_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.CLIENT_RESPONSE_HEADER_NAMES;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.PRESERVE_HOST_HEADER_ATTRIBUTE;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.isAlreadyRouted;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.setAlreadyRouted;
/**
* @author Spencer Gibb
* @author Biju Kunjummen
*/
public class NettyRoutingFilter implements GlobalFilter, Ordered {
private static final Log log = LogFactory.getLog(NettyRoutingFilter.class);
private final HttpClient httpClient;
private final ObjectProvider<List<HttpHeadersFilter>> headersFiltersProvider;
private final HttpClientProperties properties;
// do not use this headersFilters directly, use getHeadersFilters() instead.
private volatile List<HttpHeadersFilter> headersFilters;
public NettyRoutingFilter(HttpClient httpClient,
ObjectProvider<List<HttpHeadersFilter>> headersFiltersProvider,
HttpClientProperties properties) {
this.httpClient = httpClient;
this.headersFiltersProvider = headersFiltersProvider;
this.properties = properties;
}
public List<HttpHeadersFilter> getHeadersFilters() {
if (headersFilters == null) {
headersFilters = headersFiltersProvider.getIfAvailable();
}
return headersFilters;
}
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
}
@Override
@SuppressWarnings("Duplicates")
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
URI requestUrl = exchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR);
String scheme = requestUrl.getScheme();
if (isAlreadyRouted(exchange)
|| (!"http".equals(scheme) && !"https".equals(scheme))) {
return chain.filter(exchange);
}
setAlreadyRouted(exchange);
ServerHttpRequest request = exchange.getRequest();
final HttpMethod method = HttpMethod.valueOf(request.getMethodValue());
final String url = requestUrl.toString();
HttpHeaders filtered = filterRequest(getHeadersFilters(), exchange);
final DefaultHttpHeaders httpHeaders = new DefaultHttpHeaders();
filtered.forEach(httpHeaders::set);
String transferEncoding = request.getHeaders()
.getFirst(HttpHeaders.TRANSFER_ENCODING);
boolean chunkedTransfer = "chunked".equalsIgnoreCase(transferEncoding);
boolean preserveHost = exchange
.getAttributeOrDefault(PRESERVE_HOST_HEADER_ATTRIBUTE, false);
Flux<HttpClientResponse> responseFlux = this.httpClient
.chunkedTransfer(chunkedTransfer).request(method).uri(url)
.send((req, nettyOutbound) -> {
req.headers(httpHeaders);
if (preserveHost) {
String host = request.getHeaders().getFirst(HttpHeaders.HOST);
req.header(HttpHeaders.HOST, host);
}
if (log.isTraceEnabled()) {
nettyOutbound
.withConnection(connection -> log.trace("outbound route: "
+ connection.channel().id().asShortText()
+ ", inbound: " + exchange.getLogPrefix()));
}
return nettyOutbound.options(NettyPipeline.SendOptions::flushOnEach)
.send(request.getBody()
.map(dataBuffer -> ((NettyDataBuffer) dataBuffer)
.getNativeBuffer()));
}).responseConnection((res, connection) -> {
// Defer committing the response until all route filters have run
// Put client response as ServerWebExchange attribute and write
// response later NettyWriteResponseFilter
exchange.getAttributes().put(CLIENT_RESPONSE_ATTR, res);
exchange.getAttributes().put(CLIENT_RESPONSE_CONN_ATTR, connection);
ServerHttpResponse response = exchange.getResponse();
// put headers and status so filters can modify the response
HttpHeaders headers = new HttpHeaders();
res.responseHeaders().forEach(
entry -> headers.add(entry.getKey(), entry.getValue()));
String contentTypeValue = headers.getFirst(HttpHeaders.CONTENT_TYPE);
if (StringUtils.hasLength(contentTypeValue)) {
exchange.getAttributes().put(ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR,
contentTypeValue);
}
HttpStatus status = HttpStatus.resolve(res.status().code());
if (status != null) {
response.setStatusCode(status);
}
else if (response instanceof AbstractServerHttpResponse) {
// https://jira.spring.io/browse/SPR-16748
((AbstractServerHttpResponse) response)
.setStatusCodeValue(res.status().code());
}
else {
// TODO: log warning here, not throw error?
throw new IllegalStateException(
"Unable to set status code on response: "
+ res.status().code() + ", "
+ response.getClass());
}
// make sure headers filters run after setting status so it is
// available in response
HttpHeaders filteredResponseHeaders = HttpHeadersFilter.filter(
getHeadersFilters(), headers, exchange, Type.RESPONSE);
if (!filteredResponseHeaders
.containsKey(HttpHeaders.TRANSFER_ENCODING)
&& filteredResponseHeaders
.containsKey(HttpHeaders.CONTENT_LENGTH)) {
// It is not valid to have both the transfer-encoding header and
// the content-length header
// remove the transfer-encoding header in the response if the
// content-length header is presen
response.getHeaders().remove(HttpHeaders.TRANSFER_ENCODING);
}
exchange.getAttributes().put(CLIENT_RESPONSE_HEADER_NAMES,
filteredResponseHeaders.keySet());
response.getHeaders().putAll(filteredResponseHeaders);
return Mono.just(res);
});
if (properties.getResponseTimeout() != null) {
responseFlux = responseFlux.timeout(properties.getResponseTimeout(),
Mono.error(new TimeoutException("Response took longer than timeout: "
+ properties.getResponseTimeout())))
.onErrorMap(TimeoutException.class,
th -> new ResponseStatusException(HttpStatus.GATEWAY_TIMEOUT,
th.getMessage(), th));
}
return responseFlux.then(chain.filter(exchange));
}
}
@manzhizhen 检查下 arthas版本,我测试最新的 3.4.8没有问题:
我遇到同样的问题, 是因为用jrebel启动的debug模式 就会出现这种 不支持watch , trace TT等命令, 用正常模式启动就可以, 不知道是不是不支持jrebel插件.
我遇到同样的问题, 是因为用jrebel启动的debug模式 就会出现这种 不支持watch , trace TT等命令, 用正常模式启动就可以, 不知道是不是不支持jrebel插件.
是的,不使用jrebel即可绑定
我遇到同样的问题, 是因为用jrebel启动的debug模式 就会出现这种 不支持watch , trace TT等命令, 用正常模式启动就可以, 不知道是不是不支持jrebel插件.
感谢, 果然是, 我把jrebel关了正常使用调试没有问题了。