簡體   English   中英

Lambda - ClassNotFoundException

[英]Lambda - ClassNotFoundException

這是我的代碼的樣子,目前尚不清楚executorService.submit(work::get)如何/為什么會在有問題的匿名 class 上引發ClassNotFoundException 它不會一直發生,但是一旦遇到此異常,它似乎就不會恢復 - 隨后的請求會遇到相同的異常。 任何人都知道可能導致這種情況發生的原因是什么?

編輯:我可以確認,在 VM session 中,對這個方法的所有調用都有效,或者沒有一個有效 - 它不像一些成功,而另一些則由於上述異常而失敗。

package com.ab.cde.ct.service.impl;

@Service
public class IngestionService {
    @Autowired private TransactionTemplate transactionTemplate;
    @Autowired private AsyncTaskExecutor executorService;

    @Transactional
    public void ingest(Data data) {
        Supplier<Optional<String>> work = () -> transactionTemplate.execute(s -> {
            // actual work on the data object, enclosed in a try/catch/finally
        });
        executorService.submit(work::get); // this is where the exception gets thrown
    }
}

這是異常堆棧跟蹤的樣子(行號不對應,因為上面的代碼只是一個原型):

2019-10-23 19:11:35,267|[http-apr-26001-exec-10]|[B6AC864143092042BBB4A0876BB51EB6.1]|[]|[ERROR] web.error.ErrorServlet  [line:142] org.springframework.web.util.NestedServletException: Handler processing failed; nested exception is java.lang.NoClassDefFoundError: com/ab/cde/ct/service/impl/IngestionService$$Lambda$53
org.springframework.web.util.NestedServletException: Handler processing failed; nested exception is java.lang.NoClassDefFoundError: com/ab/cde/ct/service/impl/IngestionService$$Lambda$53
    at org.springframework.web.servlet.DispatcherServlet.triggerAfterCompletionWithError(DispatcherServlet.java:1275)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:951)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:867)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:951)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:853)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:827)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
Caused by: java.lang.NoClassDefFoundError: com/ab/cde/ct/service/impl/IngestionService$$Lambda$53
    at com.ab.cde.ct.service.impl.IngestionService$$Lambda$53/812375226.get$Lambda(Unknown Source)
    at com.ab.cde.ct.service.impl.IngestionService.ingest(IngestionService.java:264)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
    at com.sun.proxy.$Proxy252.ingest(Unknown Source)
Caused by: java.lang.ClassNotFoundException: com.ab.cde.ct.service.impl.IngestionService$$Lambda$53
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1364)
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1185)
    ... 115 more

這是由 lambda 生成的合成方法的情況,它無法找到所需的 class (即TransactionCallback ),因此出現以下錯誤

引起:java.lang.NoClassDefFoundError: com/ab/cde/ct/service/impl/IngestionService$$Lambda$53 at com.ab.cde.ct.service$.impl.IngestionService$$26222$53/8 (來源不明)

導致此問題的特定代碼是

Supplier<Optional<String>> work = () -> transactionTemplate.execute(s -> {
        // actual work on the data object, enclosed in a try/catch/finally
});

為了克服這個修改代碼如下

TransactionCallback<Optional<String>> callback = transactionStatus -> {
      // your processing goes here  
      return Optional.of("some value"); 
};

Supplier<Optional<String>> work = () -> transactionTemplate.execute(callback);

如果上述方法仍然不起作用,請使用以下解決方法

Object callback = (TransactionCallback<Optional<String>>)transactionStatus -> {
     // your processing goes here     
     return Optional.of("some value");
};

Supplier<Optional<String>> work = () -> transactionTemplate.execute((TransactionCallback<Optional<String>>)callback);

如果需要更多信息,請在評論中告知。

PS:如果使用transactionTemplate ,則不需要@Transactional ,因為兩者本質上都是出於相同的目的。

參考:

  1. Lambda 編譯在這里這里
  2. java中的合成方法

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM