【问题标题】:Groovy packaged into a Jar not working using maven. Caused by: java.lang.AbstractMethodErrorGroovy 打包到 Jar 中无法使用 maven。引起:java.lang.AbstractMethodError
【发布时间】:2020-06-21 11:53:37
【问题描述】:

所以我有一个 groovy 包集合,我已经使用 mvn package 成功地将它们打包成一个 jar 文件。

我成功地将这个 jar 文件添加到另一个编译得很好的项目中,但是在尝试实际使用该 jar 时出现以下错误。

Exception in thread "main" java.util.concurrent.ExecutionException: java.lang.AbstractMethodError: pefservices.restapi.Request.getProperty(Ljava/lang/String;)Ljava/lang/Object;
at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:357)
at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1915)
at org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod(IndyInterface.java:234)
at pefservices.restapi.Request.ViewPoint(Request.groovy:185)
at pefservices.restapi.Request.ViewPoint(Request.groovy)
at org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod(IndyInterface.java:234)
at pefservices.restapi.Client.profile(Client.groovy:59)
at org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod(IndyInterface.java:234)
at pefservices.restapi.Client.getName(Client.groovy:20)
at org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod(IndyInterface.java:234)
at pefservices.viewpoint.Client.<init>(Client.groovy:30)
at pefservices.viewpoint.Client.<init>(Client.groovy)
at org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod(IndyInterface.java:234)
at pefservices.viewpoint.User.<init>(User.groovy:35)
at pefservices.viewpoint.User.<init>(User.groovy)
at org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod(IndyInterface.java:234)
at pefservices.setup.Session.enableFramework(Session.groovy:188)
at pefservices.setup.Session.enableFramework(Session.groovy)
at pefservices.setup.Session$enableFramework.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:115)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:135)
at main.App.main(App.groovy:15)
Caused by: java.lang.AbstractMethodError: 
pefservices.restapi.Request.getProperty(Ljava/lang/String;)Ljava/lang/Object;
at org.codehaus.groovy.runtime.InvokerHelper.getProperty(InvokerHelper.java:190)
at groovy.lang.Closure.getPropertyTryThese(Closure.java:313)
at groovy.lang.Closure.getPropertyOwnerFirst(Closure.java:307)
at groovy.lang.Closure.getProperty(Closure.java:296)
at org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod(IndyInterface.java:234)
at pefservices.restapi.Request$_ViewPoint_closure1.doCall(Request.groovy:182)
at pefservices.restapi.Request$_ViewPoint_closure1.doCall(Request.groovy)
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.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:101)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:263)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1041)
at groovy.lang.Closure.call(Closure.java:405)
at org.codehaus.groovy.runtime.ConvertedClosure.invokeCustom(ConvertedClosure.java:50)
at org.codehaus.groovy.runtime.ConversionHandler.invoke(ConversionHandler.java:122)
at com.sun.proxy.$Proxy7.get(Unknown Source)
at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1590)
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)

下面是它失败的类,它似乎在它试图访问一个类属性时发生(我尝试从这个特定类中删除这些行,它工作得很好,但是在另一个类上失败了,它得到了另一个属性)

import java.nio.CharBuffer
import java.util.concurrent.CompletableFuture
import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit

import groovy.json.JsonOutput
import okhttp3.MediaType
import okhttp3.MultipartBody
import okhttp3.OkHttpClient
import okhttp3.Request as Req
import okhttp3.RequestBody
import okhttp3.Response
import okhttp3.OkHttpClient.Builder as ClientBuilder
import okhttp3.Request.Builder
import okio.Buffer
import pefservices.restapi.User as UserAPI
import pefservices.setup.*

public class Request {

Map <String, String> cache = new HashMap <String, String>()
Map <String, CompletableFuture <?>> inProcess = new HashMap <String, CompletableFuture <?>>()

//includes Authorization

public def ViewPoint(String url, String RequestMethod, def requestBody='', Map headers=[:], boolean asAdmin=true, def asUser=null) {

    if(!url.startsWith("http://"))
    {

        url='http://'+url
    }
    String toBeCached = url+RequestMethod+requestBody+headers+Values+asAdmin+asUser


    waitForRequestifExists(toBeCached)

    if(!cache.containsKey(toBeCached))
    {
        def inputLine
        inProcess.put(toBeCached, new CompletableFuture().supplyAsync(
                {
                    OkHttpClient client = new ClientBuilder().connectTimeout(120, TimeUnit.SECONDS).readTimeout(120, TimeUnit.SECONDS).build();



                    println "restAPI [$RequestMethod] URL: "+url

                    Builder builder =new Builder().url(url)

//                  headers+=["Accept-Encoding" :"gzip, deflate"]
                    headers+=["Accept"          :"application/json, text/plain, */*"]
                    headers+=["Accept-Language" :"en-US,en;q=0.5"]
                    headers+=["Expires"         :"-1"]
                    headers+=["Connection"      :"keep-alive"]

                    if(requestBody instanceof File)
                    {
                        String boundary = "-------------" + System.currentTimeMillis();
                        headers+=['Content-Type':'multipart/form-data; boundary='+boundary]



                    }

                    if(!headers.containsKey("Content-Type"))
                    {
                        headers+=["Content-Type"    :"application/json; charset=UTF-8; odata.metadata=minimal"]
                    }

                    if (!url.contains("api/open") && url.contains(Session.url))
                    {
                        if (asAdmin==true)
                        {
                            headers+=["Authorization"   :Session.tokens['adminToken']];
                        }
                        else if(asUser!=null)
                        {
                            UserAPI userAPI = new UserAPI();
                            headers+=["Authorization"   :userAPI.loginPost(asUser).Token]
                        }
                        else{
                            headers+=["Authorization"   :Session.tokens['userToken']];
                        }
                    }

                    for(entry in headers) {
                        builder.addHeader(entry.key, entry.value)

                    }



                    if (!(requestBody instanceof String) && headers['Content-Type'].toString().contains("json"))
                    {

                        requestBody = JsonOutput.toJson(requestBody)

                    }


                    if (RequestMethod != 'GET')
                    {

                        try{
                            println "Json body:->"+ JsonOutput.prettyPrint(requestBody)
                        }
                        catch (Throwable ex)
                        {
                            println "body:"+ requestBody
                        }
                        if(requestBody instanceof File)
                        {
                            RequestBody body = RequestBody.create(MediaType.parse(headers['Content-Type']), requestBody)
                            RequestBody formBody = new MultipartBody.Builder()
                                    .setType(MultipartBody.FORM)
                                    .addFormDataPart("file", requestBody.getName(), body)
                                    .build()

                            builder.method(RequestMethod, formBody)

                        }
                        else{

                            RequestBody body = RequestBody.create(MediaType.parse(headers['Content-Type']), requestBody)
                            builder.method(RequestMethod, body)
                        }
                    }
                    Req request = builder.build()

                    Response response = client.newCall(request).execute()

                    int responseCode = response.code()
                    String responseTitle = response.message()

                    if(response.header("Content-Disposition")?.contains('attachment'))
                    {
                        String header =response.header("Content-Disposition")
                        String fileExtension = header.substring(header.lastIndexOf('.'))
                        println "Content-Disposition: attachment  - File Extension ->$fileExtension"

                        File file = new File(".\\TestFiles\\temp$fileExtension")
                        InputStream IS= response.body().byteStream()

                        BufferedInputStream input = new BufferedInputStream(IS);
                        OutputStream output = new FileOutputStream(file);

                        byte[] data = new byte[1024];
                        long total = 0

                        int count
                        while ((count =input.read(data)) != -1) {

                            total += count;
                            output.write(data, 0, count);
                        }
                        output.flush();
                        output.close();
                        input.close();
                        inputLine = file
                    }
                    else
                    {


                        inputLine = response.body().string()
                    }

                    println "RESTAPI Response Code: -> "+ responseCode 
                    if (responseCode >= 400)
                    {
                        println "Message: -> " + responseTitle
                        println "Error Resposne body:  -> "+inputLine
                        throw new Exception("Error Code =$responseCode   URL:  $url")
                    }

在下面一行中特别失败

                    cache[toBeCached] = inputLine
                }, new Executors().newSingleThreadExecutor()))

        inProcess[toBeCached].get(120, TimeUnit.SECONDS)
        inProcess.remove(toBeCached)

        if(RequestMethod == "POST")
            {println "restapi.Request() ->"+inputLine

            }
        return inputLine
    }
    else
    {
        return cache.get(toBeCached)
    }


}
public void waitForRequestifExists(String key)
{
    if(inProcess.containsKey(key))
    {
        this.inProcess[key].get(120, TimeUnit.SECONDS)
    }
}
public void clearCache()
{
    this.cache = new HashMap <String, String>()
    this.inProcess = new HashMap <String, CompletableFuture <?>>()
}
}

【问题讨论】:

  • 你用哪个 maven 插件来编译 groovy 文件?

标签: java maven groovy jar


【解决方案1】:

我在我们的 maven 项目中看到了 AbstractMethodError。似乎问题在于 groovy-all 和 groovy-eclipse-batch 的版本应该匹配。来自 groovy-eclipse issue 的 eric-milles 的评论很有帮助。

【讨论】:

    【解决方案2】:

    我遇到了类似的问题,原来用于编译 groovy 代码的 maven 插件有一些问题。我通过使用this answer 解决了它。

    基本上您需要明确指定groovy-eclipse-compilergroovy-eclipse-batch 的版本。在我的 POM 中,我将 metaversion 值设置为 LATEST。相反,请尝试使用具体的值,例如 &lt;version&gt;3.6.0-03&lt;/version&gt;。 (之后尝试清除您的 .m2 存储库缓存。)

    这适用于您在构建过程中使用这些插件的情况。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-08
      • 1970-01-01
      • 1970-01-01
      • 2023-03-27
      • 2020-01-25
      • 2013-02-15
      • 2018-10-04
      • 1970-01-01
      相关资源
      最近更新 更多