无法使用运行时依赖项进行编译,但可以使用编译

时间:2019-09-02 16:13:37

标签: java maven okta

我有一个多模块项目,在一个模块中,我试图按照自述文件中的说明添加Okta-SDK依赖项:

<properties>
  <okta.version>1.5.4</okta.version>
</properties>
<dependency>
    <groupId>com.okta.sdk</groupId>
    <artifactId>okta-sdk-api</artifactId>
    <version>${okta.version}</version>
</dependency>
<dependency>
    <groupId>com.okta.sdk</groupId>
    <artifactId>okta-sdk-impl</artifactId>
    <version>${okta.version}</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>com.okta.sdk</groupId>
    <artifactId>okta-sdk-httpclient</artifactId>
    <version>${okta.version}</version>
    <scope>runtime</scope>
</dependency>

但它不能与mvn clean package -pl my-module一起编译,它会因错误而失败:

[ERROR] COMPILATION ERROR : 
[INFO] -------------------------------------------------------------
[ERROR] /some/path/OktaUsers.java:[9,38] error: package com.okta.sdk.impl.resource.user does not exist
[ERROR] /some/path/OktaUsers.java:[96,14] error: cannot find symbol
[ERROR]  class OktaUsers
/some/path/OktaUsers.java:[97,13] error: cannot find symbol
[INFO] 3 errors 

此类OktaUsers引用了Okta-SDK类。但是,如果我将runtime工件的compile范围更改为okta-sdk-impl

<dependency>
    <groupId>com.okta.sdk</groupId>
    <artifactId>okta-sdk-impl</artifactId>
    <version>${okta.version}</version>
    <scope>compile</scope>
</dependency>

然后编译完成正常:mvn clean package -pl my-module

[INFO] BUILD SUCCESS

但是由于依赖关系问题,最终应用无法正常运行:

java.lang.NoClassDefFoundError: Could not initialize class com.okta.sdk.impl.ds.DefaultDataStore
    at com.okta.sdk.impl.client.AbstractClient.createDataStore(AbstractClient.java:73)
    at com.okta.sdk.impl.client.AbstractClient.<init>(AbstractClient.java:68)
    at com.okta.sdk.impl.client.DefaultClient.<init>(DefaultClient.java:99)
    at com.okta.sdk.impl.client.DefaultClientBuilder.build(DefaultClientBuilder.java:305)

我认为在编译时,所有具有runtime范围的依赖项都应该可用。但似乎并非如此。如何解决此问题?我需要在编译和运行时都具有这种依赖性。


更新:

由于它是私有的,因此我无法共享该项目的源,但是这里是OktaUser类的一些行:

import com.okta.sdk.client.Client;
import com.okta.sdk.impl.resource.user.DefaultRole;
import com.okta.sdk.resource.group.Group;
import com.okta.sdk.resource.group.GroupBuilder;
import com.okta.sdk.resource.user.Role;
import com.okta.sdk.resource.user.RoleStatus;
import com.okta.sdk.resource.user.UserBuilder;
import com.okta.sdk.resource.user.UserProfile;


public final class OktaUsers implements Users {

    private final Client okta;


// line 95:
    private Role adminRole() {
        final DefaultRole role =
            (DefaultRole) this.okta.instantiate(Role.class);
        role.setProperty("type", "USER_ADMIN");
        role.setProperty("status", RoleStatus.ACTIVE);
        return role;
    }
}

我在这里使用impl依赖中的类,因为api dep没有管理Okta角色的方法。


运行mvn verify -pl my-module

时,此代码可以很好地用于集成测试

Maven版本:

Apache Maven 3.6.1 (d66c9c0b3152b2e69ee9bac180bb8fcc8e6af555; 2019-04-04T22:00:29+03:00)
Maven home: /usr/share/maven-bin-3.6
Java version: 1.8.0_212, vendor: IcedTea, runtime: /opt/icedtea-bin-3.12.0/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "4.19.44-gentoo", arch: "amd64", family: "unix"

2 个答案:

答案 0 :(得分:1)

您可以发布/some/path/OktaUsers.java的内容吗?此类似乎取决于Okta IMPL包中的类。如果我正确理解Okta API,则您自己的代码应该仅依赖/使用API​​模块中的类,而不依赖impl模块。如果您从impl模块中删除了对类的依赖,那么应该没问题。

修改1: 我看到两种方法。您可以删除对DefaultRole的依赖。

// line 95:
private Role adminRole() {
    Role role = this.okta.instantiate(Role.class);
    role.setType("USER_ADMIN");
    // use reflection to check if there is a setProperty() method
    // and call it if it's really necessary
    // role.setProperty("status", RoleStatus.ACTIVE);
    return role;
}

第二种方法是找出为什么jvm无法实例化com.okta.sdk.impl.ds.DefaultDataStore。这可能是一个非常繁琐的任务,因为jvm不会向您显示正确的错误消息。我猜想类路径中缺少依赖项。您需要查看类的源,并确保所有引用的类(以及这些类引用的所有类,依此类推)都在类路径上。这样做时,您需要确保使用了这些类的正确版本,即,与之建立参照类的版本相同。对于初学者,请确保org.slf4j.Logger和记录器的单个实现在类路径上并且已正确配置。

正确的解决方法是更改​​api。 okta问题列表中似乎有一个已解决的issue,描述了类似的问题。也许这可以帮助您?如果没有,我建议与okta开发人员联系,并询问他们如何解决您的问题。

答案 1 :(得分:1)

具有范围runtime的依赖项仅在运行时可用,而在编译时不可用。这是用于不应直接调用的实现jar和框架jar。

在编译时和运行时都可以使用具有范围compile的依赖项。