2015-12-31 53 views
4

我想从Android工作室运行一个jar。经过长时间的解决方案后,该jar文件运行完美。在Android Studio中导出包含Manifest属性的Jar文件?

现在我需要从android工作室导出jar文件。我从build/libs文件夹中获得了Jar文件。

但问题是jar文件显示错误。

无主清单属性,在 “app.jar”

所以我发现了这个解决方案。 Can't execute jar- file: "no main manifest attribute"

然后我读了关于MANIFEST.MF &添加邮件类到该文件。

jar { 
    manifest.attributes(
      'Main-Class': "com.Remo.server.RemoServerApp" 
    ) 
} 

将这些添加到我的gradle中后。我的MANIFEST.MF包含MainClass。

但我仍然得到同样的错误?我该如何解决这个问题?

注意:目标是我想从项目导出一个Runnable Jar文件。

UPDATE:

在MANIFEST.MF添加MainClass后。我陷入了下面的错误。

Exception in thread "main" java.lang.NoClassDefFoundError: com/Remo/protocol/RemoConnection 
    at com.Remo.server.RemoServerApp.<init>(RemoServerApp.java:33) 
    at com.Remo.server.RemoServerApp.main(RemoServerApp.java:97) 
Caused by: java.lang.ClassNotFoundException: com.Remo.protocol.RemoConnection 
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424) 
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357) 
    ... 2 more 

MANIFEST.MF

清单-版本:1.0
主类:com.Remo.server.RemoServerApp

更新2

从您的解决方案是什么我了解到,我们需要将remoprotocol jar文件复制到remoserver。

remoserver项目gradle这个文件

apply plugin: 'java' 

sourceSets { 
    main { 
     resources.srcDirs = ['src/main/resources'] 
    } 
} 

dependencies { 
    compile project(':remoprotocol') 
    compile files('libs/bluecove-2.1.1.jar') 
} 

jar { 
    manifest.attributes(
      'Main-Class': "com.remo.server.remoServerApp" 
    ) 
    manifest.attributes(
      'Class-Path': configurations.runtime.files.collect { it.getName() }.join(' ')) 
} 

task copyRTDependenciesToLib(type: Copy) { 
    into "$buildDir/output/lib" 
    from configurations.runtime 
} 

运行gradle这个任务还我收到了同样的错误后。

+0

听起来像是你需要添加classpath以及你的清单。你能发布完整的manifest.mf吗? – RaGe

+0

是这个jar中包含的'com/Remo/protocol/RemoConnection'类吗?或者有没有任何外部依赖罐? – RaGe

+0

@RaGe我已经将build.gradle文件中的协议模块作为依赖项引用。但它们不包含在我的jar文件中。我如何添加它们? – user3467240

回答

4

首先,您要将所有运行时依赖关系复制到builddir/libs文件夹(如果您愿意,可以选择不同的分发文件夹)。这里是一个自定义任务,将实现这一点:

task copyRTDependenciesToLib(type: Copy) { 
    into "$buildDir/libs" 
    from configurations.runtime 
} 

加入你的运行依赖罐子在你的清单文件中的Class-Path属性。这些罐子需要和你的可运行罐子在同一个目录下 - 上面的复制任务可以达到这个目的。 (或者,你可以对你的依赖罐子位置提供完整的相对路径)

jar { 
    manifest { 
     attributes(
      "Main-Class": "com.Remo.server.RemoServerApp", 
      "Class-Path": configurations.runtime.files.collect { it.getName() }.join(' ')) 
     ) 
    } 
} 

做更多的事情要考虑:

  • application插件做同样的事情;它添加了一个任务installDist,该任务生成一组可运行的jar以及任何依赖项,任何自述文件,要包含的文档。

  • 如果你想制作一个可运行的罐子,而无需捆绑与它一起的依赖,你应该考虑创建一个“fatjar”,例如:

    task fatJar(type: Jar) { 
        manifest { 
         attributes 'Implementation-Title': 'Gradle Jar File Example', 
          'Implementation-Version': version, 
          'Main-Class': "com.Remo.server.RemoServerApp" 
        } 
        baseName = project.name 
    
        //collect all dependencies 
        from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } 
        with jar 
    } 
    
+0

这些子项目是否属于父项目?还是独立的项目? – RaGe

+0

在任何一种情况下,也可能存在其他外部依赖关系,创建自定义副本任务可能最简单,可将所有运行时依赖关系复制到可运行jar项目的build/lib文件夹中。 – RaGe

+0

您可能还希望收集与可运行jar相同的文件夹中的所有依赖关系jar。为了反映这一点,我对答案做了修改。 – RaGe

-1

我没有使用Android Studio(或Gradle)的经验,但我有Java。你不是试图设置主类吗?

因此,我建议改变Class-Path属性Main-Class的清单应该包含主类,以能够调用的东西时,“运行” JAR。

+0

这是作为答案发布的,但它不会尝试回答问题。它应该可能是编辑,评论,另一个问题,或者完全删除。 –

+0

如果您正确地阅读我的回复,您可以在那里看到一个建议,这可能会导致(或很可能)回答问题。所以我会重新修改它,然后删除问号。 –

相关问题