当前位置: 首页 > 知识库问答 >
问题:

无法启动在liferay 7中嵌入spring boot OSGI包

公羊曜灿
2023-03-14

我想开发一个使用spring boot和spring data jpa(不带web)实现服务的独立包。该包旨在创建一个spring上下文以方便存储库的创建,并且在包激活器中,我创建了Spring Boot应用程序,获得了使用注入的存储库的服务的实现,并且该服务将注册为OSGI服务。

bundle将部署在Liferay7上,因此没有现成的bundle来帮助导出包(对于jpa...)。为了更简单起见,有一个独立的bundle将所有依赖项嵌入到bundle类路径中(没有从bundle外部导入的包)

有什么样本能帮上忙吗?这是个好主意吗?

问题是,当尝试启动包时,它失败了,“caused by:java.lang.ClassNotFoundException:org.osgi.framework.BundleActivator..”

下面的类被简化成sampel来描述问题(通常,它必须是一个单独的包,用来定义和导出将由所讨论的包实现的api,但在本示例中,它是一个包含4个类的唯一包)

1/捆绑激活器类

import java.util.Hashtable;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.springframework.context.ApplicationContext;

public class Activator implements BundleActivator
{
  @Override
  public void start(BundleContext context) throws Exception
  {
    ApplicationContext springCtx = SpringFramework.getContext();
    UserDao dao = springCtx.getBean(UserDao.class);
    userDaoReg = bc.registerService(UserDao.class.getName(), dao, new Hashtable());
  }

  @Override
  public void stop(BundleContext context) throws Exception
  {
    /** **/
  }
}

2/类启动Spring Boot应用程序

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class SpringFramework {

  private static ConfigurableApplicationContext context;

  public static void main(String[] args) {
    context = SpringApplication.run(SpringFramework.class);
  }

  public static ConfigurableApplicationContext getContext()
  {
    if (context == null) {
        context = SpringApplication.run(SpringFramework.class);
    }
    return context;
  }
}
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserDao extends JpaRepository<User, Integer>
{
}

这些是pom.xml中使用的依赖项和插件

<dependencies>
<!--OSGI dependencies-->
  <dependency>
    <groupId>org.osgi</groupId>
      <artifactId>org.osgi.core</artifactId>
      <scope>provided</scope>
    </dependency>

    <!-- Spring -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
    </dependency>
   <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-data-jpa</artifactId>
   </dependency>
   <!--persistence-api -->
   <dependency>
     <groupId>javax.persistence</groupId>
     <artifactId>persistence-api</artifactId>
   </dependency>
 </dependencies>
 <build>
  <plugins>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
      <version>1.3.0.RELEASE</version>
    </plugin>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-jar-plugin</artifactId>
      <version>2.6</version>
      <configuration>
        <archive>
          <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
        </archive>
      </configuration>
    </plugin>
    <plugin>
      <groupId>org.apache.felix</groupId>
      <artifactId>maven-bundle-plugin</artifactId>
      <version>3.2.0</version>
      <executions>
        <execution>
          <id>bundle-manifest</id>
          <phase>process-classes</phase>
          <goals>    
            <goal>manifest</goal>
          </goals>
          <configuration>
            <instructions>
              <Import-Package>!*</Import-Package>
              <Bundle-Activator>hello.Activator</Bundle-Activator>
              <Embed-Dependency>*</Embed-Dependency>
              <!--<Embed-Transitive>true</Embed-Transitive>-->
            </instructions>
          </configuration>
        </execution>
      </executions>
    </plugin>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
      <executions>
        <execution>
          <goals>
            <goal>repackage</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

这是在jar中生成的清单

Manifest-Version: 1.0
Bundle-SymbolicName: test-spring-boot-no-web
Archiver-Version: Plexus Archiver
Built-By: XXX
Bnd-LastModified: 1475774161783
Bundle-ManifestVersion: 2
Embed-Dependency: *
Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))"
Spring-Boot-Version: 1.3.0.RELEASE
Tool: Bnd-3.2.0.201605172007
Main-Class: org.springframework.boot.loader.JarLauncher
Embedded-Artifacts: org.osgi.core-6.0.0.jar;g="org.osgi";a="org.osgi.c
 ore";v="6.0.0",slf4j-api-1.7.13.jar;g="org.slf4j";a="slf4j-api";v="1.
 7.13",spring-boot-starter-1.3.0.RELEASE.jar;g="org.springframework.bo
 ot";a="spring-boot-starter";v="1.3.0.RELEASE",spring-boot-starter-dat
 a-jpa-1.3.0.RELEASE.jar;g="org.springframework.boot";a="spring-boot-s
 tarter-data-jpa";v="1.3.0.RELEASE",persistence-api-1.0.2.jar;g="javax
 .persistence";a="persistence-api";v="1.0.2",javax.transaction-api-1.2
 .jar;g="javax.transaction";a="javax.transaction-api";v="1.2"
Export-Package: hello;version="1.0.0"
Bundle-Name: spring-boot-no-web
Bundle-Version: 1.0.0.SNAPSHOT
Bundle-ClassPath: .,org.osgi.core-6.0.0.jar,slf4j-api-1.7.13.jar,sprin
 g-boot-starter-1.3.0.RELEASE.jar,spring-boot-starter-data-jpa-1.3.0.R
 ELEASE.jar,persistence-api-1.0.2.jar,javax.transaction-api-1.2.jar
Bundle-Activator: hello.Activator
Start-Class: hello.SpringFramework
Created-By: Apache Maven Bundle Plugin
Build-Jdk: 1.8.0_101

共有1个答案

仲孙疏珂
2023-03-14

我在你的帖子里看到了两个问题,所以我会试着回答这些问题:

有什么样本能帮上忙吗?

我不这么认为!你想做的事在我看来很奇怪。详见下文。

没有所谓的“独立捆绑”。我假设您指的是独立的java应用程序(嵌入了OSGi框架的可执行Jar文件)。您可以以多种不同的方式构建此类应用程序。例如,有很好的教程如何做到这一点从途中。但是,您不能部署这样的可执行jar,因为它通常不是OSGi包。虽然技术上您可以使它成为一个捆绑包,但由于嵌入的运行时和依赖项,您可能会遇到各种问题。

在Liferay7(以及任何具有OSGi容器的其他产品)中,您可以在产品定义的运行时环境中运行包。包必须在运行时可解析。它可能嵌入了它的所有依赖项,但这违背了模块化的目的,除非它提供了一些东西到bundle的外部(这似乎不是您的情况)。

从这个角度来看,你想做的似乎是个坏主意。此外,Spring Boot是一个构建独立java应用程序的框架,因此它有自己的假设。让它在OSGi容器中工作可能不是一件简单的事情(如果可能的话)

也许更好的办法是让一些包只提供业务逻辑。然后,您可以在Liferay和La中部署这些包,使Liferay的功能为REST服务器服务。您可以使用完全相同的bundle来cunstruct使用Spring、CXF或其他东西的独立应用程序。

>

  • 您的主要类是org.springframework.boot.loader.jarlauncher。如果运行这个jar,它将启动Spring,而Spring可能完全不知道OSGI运行时。
  • 您有org.osgi.core-6.0.0.jar是您的包的类路径,基本上是OSGi的运行时。如果部署到OSGi运行时,这将导致问题,我就是您看到的原因

    原因:java.lang.ClassNotFoundException:org.osgi.framework.BundleActivator.

  •  类似资料: