Open anitadc opened 4 years ago
@anitadc Thank you for contacting me. Are you using Spring Boot Maven Plugin in your build?
Yes. I am using spring-boot-maven-plugin 2.1.2
@anitadc Thank you for your reply. I ported the code sample Basic Parser to a Spring Boot application. Please find the attatched project. justify-examples-spring-boot.zip It seems to work fine. Please tell me if there exists difference from your project.
Difference is - I am calling this justify parser asynchronously using completablefuture and external executor
Can you provide me with a sample project that reproduces the reported problem?
To generate issue, initialize JsonValidationService within child thread instead of static or Singleton object.
Do below changes In your sample project - https://github.com/leadpony/justify/files/3916858/justify-examples-spring-boot.zip
CompletableFuture.runAsync(()-> { JsonValidationService service = JsonValidationService.newInstance() ; ....... validate(arg1[0], arg2[1]); ..... }) .exceptionally((Throwable e)-> LOG.error(e); return null; });
Thank you @anitadc
With your help, I reproduced the problem finally using both spring-boot-maven-plugin and CompletableFuture
.
However the same problem occurs even without Justify.
Could you please run the following code?
@SpringBootApplication
public class Application implements CommandLineRunner {
private static final Logger LOG = LoggerFactory.getLogger(Application.class);
@Override
public void run(String... args) throws Exception {
var future = CompletableFuture.runAsync(() -> {
JsonProvider provider = loadProvider();
LOG.info(provider.getClass().getName());
}).exceptionally(e -> {
LOG.error(e.getMessage());
return null;
});
future.get();
}
private JsonProvider loadProvider() {
ServiceLoader<JsonProvider> loader = ServiceLoader.load(JsonProvider.class);
Iterator<JsonProvider> it = loader.iterator();
if (it.hasNext()) {
return it.next();
} else {
throw new IllegalStateException("No service provider found");
}
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
pom.xml (with Justify removed)
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>jakarta.json</groupId>
<artifactId>jakarta.json-api</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>jakarta.json</artifactId>
<classifier>module</classifier>
<version>${jakarta.json.version}</version>
<scope>runtime</scope>
</dependency>
</dependencies>
Therefore this is NOT a problem of Justify. I suspect that the problem is due to a restriction or bug of spring-boot-maven-plugin using with ServiceLoader
class.
I added a fallback logic to JsonValidationService#newInstance(). Could you please test with the current snapshot? See Building from Source section in the top page of this repository.
Thank you @anitadc With your help, I reproduced the problem finally using both spring-boot-maven-plugin and
CompletableFuture
. However the same problem occurs even without Justify. Could you please run the following code?@SpringBootApplication public class Application implements CommandLineRunner { private static final Logger LOG = LoggerFactory.getLogger(Application.class); @Override public void run(String... args) throws Exception { var future = CompletableFuture.runAsync(() -> { JsonProvider provider = loadProvider(); LOG.info(provider.getClass().getName()); }).exceptionally(e -> { LOG.error(e.getMessage()); return null; }); future.get(); } private JsonProvider loadProvider() { ServiceLoader<JsonProvider> loader = ServiceLoader.load(JsonProvider.class); Iterator<JsonProvider> it = loader.iterator(); if (it.hasNext()) { return it.next(); } else { throw new IllegalStateException("No service provider found"); } } public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
pom.xml (with Justify removed)
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>jakarta.json</groupId> <artifactId>jakarta.json-api</artifactId> </dependency> <dependency> <groupId>org.glassfish</groupId> <artifactId>jakarta.json</artifactId> <classifier>module</classifier> <version>${jakarta.json.version}</version> <scope>runtime</scope> </dependency> </dependencies>
Therefore this is NOT a problem of Justify. I suspect that the problem is due to a restriction or bug of spring-boot-maven-plugin using with
ServiceLoader
class.
Correct. This will happen with any code like justify which will use ServiceLoader and current thread classloader.
I added a fallback logic to JsonValidationService#newInstance(). Could you please test with the current snapshot? See Building from Source section in the top page of this repository.
I appreciate this change. Hopefully this will work. I will confirm you.
Did you add this fallback logic in 2.1.0 version?? Kindly publish this in maven repository.
@anitadc
You need to build and install it to your local repository by yourself.
If it works well with your application, I will publish it as the next official release.
Please follow the instruction in the section Building from Source.
You also need to change the version of the dependency in your pom.xml to 2.1.0-SNAPSHOT
Thank you for your cooperation.
I am facing same problem when running Spring boot application jar from command prompt. But It is working fine from eclipse and same application jar in other machine. I am using java11 and no module structure.
Originally posted by @anitadc in https://github.com/leadpony/justify/issues/18#issuecomment-560415481