使用Spring Boot打包时找不到Jython模块?

时间:2015-12-07 22:42:30

标签: spring-boot jetty jython

我正在使用Spring Boot,Jython和Pygments与Maven一起工作,并且在Maven打包步骤之后尝试启动应用程序时出现了一个奇怪的错误。

在IDE( Eclipse Luna )中启动以及在使用mvn spring-boot:run时,在初始开发过程中已成功运行。

使用spring-boot-maven-plugin创建可执行jar后,导航到生成的target目录并使用java -jar app-0.0.1.jar启动 - 我看到错误:

2015-12-07 16:05:11.131  INFO 6890 --- [           main] app.Application                      : Starting Application v0.0.1 on localhost with PID 6890 (/Users/me/Code/EclipseWorkspaces/app/app-0.0.1.jar started by me in /Users/me/Code/EclipseWorkspaces/app/target)
2015-12-07 16:05:11.135  INFO 6890 --- [           main] app.Application                      : No profiles are active
2015-12-07 16:05:12.418  INFO 6890 --- [           main] org.eclipse.jetty.server.Server          : jetty-9.2.14.v20151106
2015-12-07 16:05:12.489  INFO 6890 --- [           main] application                              : Initializing Spring embedded WebApplicationContext
2015-12-07 16:05:12.970  INFO 6890 --- [           main] org.eclipse.jetty.server.Server          : Started @2685ms
2015-12-07 16:05:14.536  WARN 6890 --- [           main] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'syntaxHighlighterService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void app.service.SyntaxHighlighterService.setSyntaxHighlighter(app.pygments.SyntaxHighlighter); nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'syntaxHighlighter' defined in class path resource [app/config/SyntaxHighlighterConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [app.pygments.SyntaxHighlighter]: Factory method 'getSyntaxHighlighter' threw exception; nested exception is Traceback (most recent call last):
  File "__pyclasspath__/PygmentsSyntaxHighlighter.py", line 2, in <module>
  File "__pyclasspath__/pygments/__init__.py", line 37, in <module>
  File "__pyclasspath__/pygments/util.py", line 12, in <module>
ImportError: No module named re
...

我通过Maven POM中的spring-boot-starter-parent BOM使用Spring Boot版本1.3.0.RELEASE。另外,我排除了默认的Tomcat服务器,转而支持Jetty。

我唯一的猜测是,由于Spring Boot如何将jar依赖项嵌入到生成的打包的可执行jar中的/lib文件夹中,但是到目前为止,解决错误仍然是不成功的,因此存在一些类加载器混淆。 / p>

有人可以就如何更好地诊断错误甚至直接修复提出建议吗?

2 个答案:

答案 0 :(得分:2)

Spring boot已经有了这样的机制:https://docs.spring.io/spring-boot/docs/current/reference/html/howto-build.html#howto-extract-specific-libraries-when-an-executable-jar-runs

  

84.6运行可执行jar时提取特定库大多数可执行jar中的嵌套库不需要解压缩   但是,为了运行,某些库可能会出现问题。对于   例如,JRuby包含它自己的嵌套jar支持,它假设   jruby-complete.jar总是直接作为文件提供   自己的权利。

     

要处理任何有问题的库,您可以标记该特定的库   嵌套的jar应该自动解压缩到'temp文件夹'时   可执行jar首先运行。

     

例如,要指示应使用标记来解压缩JRuby   Maven插件你可以添加以下配置:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <requiresUnpack>
                    <dependency>
                        <groupId>org.jruby</groupId>
                        <artifactId>jruby-complete</artifactId>
                    </dependency>
                </requiresUnpack>
            </configuration>
        </plugin>
    </plugins>
</build>
     

与Gradle做同样的事情:

springBoot  {
    requiresUnpack = ['org.jruby:jruby-complete']
}

在jython的情况下,您将使用org.python:jython-standalone

答案 1 :(得分:0)

我遇到了类似的问题,这就是我以一种不那么优雅的方式解决它的方法。首先,我将jython发行版的python库(Lib目录)作为zip文件打包到我的项目资源中。

在春季班我引用它:

private org.springframework.core.io.Resource jython = new ClassPathResource(“lib.zip”);

然后在代码中将它从spring boot jar写入临时zipfile:

    Path jythonTempFile = Files.createTempFile(null, "lib.zip");
    jythonTempFile.toFile().deleteOnExit();

    InputStream jythonInputStream = jython.getInputStream();
    Files.copy(jythonInputStream, jythonTempFile, StandardCopyOption.REPLACE_EXISTING);

    String jythonPath = jythonTempFile.toFile().getAbsolutePath();

然后在设置Python解释器时使用该tempfile的路径:

    PythonInterpreter interp = new PythonInterpreter();
    interp.exec("sys.path.append('" + jythonPath + "')");

这样你也可以在Jython解释器中添加其他类和python库。

为什么这不优雅?现在这些库在spring引导应用程序中是两次,一次在jython.jar中,一次在zip中。

我没有时间找出以防弹方式获取引导内jython库的方法。