IllegalStateException when running with Java SDK outside of IDE

I’m working on a standalone Java8 program to fetch data from the Okta syslog API using the Okta Java SDK. I’m using Maven to build and have the following in my pom.xml:

 <properties>
  ...
  <okta.version>1.5.4</okta.version>
  ...
</properties>
...
<dependencies>
  <dependency>
    <groupId>com.okta.sdk</groupId>
    <artifactId>okta-sdk-api</artifactId>
    <version>${okta.version}</version>
    <scope>compile</scope>
  </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>
</dependencies>

Everything works fine when I run the program from within IntelliJ. However, when I build my jars and run from the command line, I get the following error:

Unable to find a 'com.okta.sdk.impl.http.RequestExecutorFactory' implementation on the classpath.  Please ensure you have added the okta-sdk-httpclient.jar file to your runtime classpath.
...
Caused by: java.lang.IllegalStateException: Unable to find a 'com.okta.sdk.impl.http.RequestExecutorFactory' implementation on the classpath.  Please ensure you have added the okta-sdk-httpclient.jar file to your runtime classpath.
	at com.okta.commons.lang.Classes.lambda$loadFromService$0(Classes.java:205) ~[?:?]
	at java.util.Optional.orElseThrow(Optional.java:290) ~[?:1.8.0_241]
	at com.okta.commons.lang.Classes.loadFromService(Classes.java:205) ~[?:?]
	at com.okta.sdk.impl.client.BaseClient.createRequestExecutor(BaseClient.java:103) ~[?:?]
	at com.okta.sdk.impl.client.BaseClient.<init>(BaseClient.java:72) ~[?:?]
	at com.okta.sdk.impl.client.AbstractClient.<init>(AbstractClient.java:60) ~[?:?]
	at com.okta.sdk.impl.client.DefaultClient.<init>(DefaultClient.java:117) ~[?:?]
	at com.okta.sdk.impl.client.DefaultClientBuilder.build(DefaultClientBuilder.java:322) ~[?:?]
	... 13 more

Is there something wrong with my pom.xml? Am I missing some critical component?

I tried running my server from the command line with the -verbose:class option and I can see that the JVM is loading classes from my .jar file. I can see that it’s loading classes from okta-sdk-api and okta-sdk-impl but I do not see it loading the classes from okta-sdk-httpclient even though I know those classes are in the .jar file (because I unzipped it and looked).

just include this runtime dependency into your uber jar

Update - Found a fix. This is a threads and classloader issue.

In my case, I’m creating a factory object which will create my Okta Client object at some time in the future and then passing that factory object into a new thread.

Okta SDK uses java.util.ServiceLoader.load(java.lang.Class) to load its implementation. This will use the thread context class loader, which in my case is wrong because the thread context classloader doesn’t see the Okta SDK classes. I fixed it by temporarily setting the thread context class loader to the factory class’s classloader prior to building my Okta client.

My factory class now looks like this:

public Client getOktaClient(String oktaDomain, String oktaApiKey) {
  ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
  try {
    Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
    return Clients.builder()
      .setClientCredentials(new TokenClientCredentials(oktaApiKey))
      .setOrgUrl(oktaDomain)
      .build();
  } finally {
    Thread.currentThread().setContextClassLoader(originalClassLoader);
  }
}

See https://stackoverflow.com/a/36228195

using this class loader fix, i was able to resolve this same issue mentioned in this thread. But my application was not a standalone one, it was a web app running on a server but i still went ahead and tried it. it resolved the solution but i am still not in favor of using it in production deployed code. i will be interested in knowing the root cause but for now it worked. thanks.

Can you put it on Github, so we can better understand it?

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.