IntelliJ run vs running a jar, with a Springboot Kotlin, Multi module Gradle project with Social Oauth2

717 Views Asked by At

TL;DR: Why does everything run fine when started via IntelliJ, and why is it broken when call java -jar app.jar. And how do I fix this?


Alright, I have some issues with a backend I am trying to dockerize. I have an application created with Spring Boot (1.4.2.RELEASE) following the Spring Oauth (2.0.12.RELEASE) guide on their page. I follow the Gradle version, since I prefer Gradle over Maven. Also I am using Kotlin instead of Java. Everything is fine, I start via IntelliJ my backend with static front end, I can login via Facebook (and Google and Github), I receive a nice Principal witch holds al the information I need, and I can modify Spring Security to authorize and permit endpoints. So far so good.

Now for the bad part, when I run either ./gradlew clean build app:bootrun or ./gradlew clean build app:jar and run the jar via java -jar (like I will do in my Docker container), my backend comes up. My static front end pops up. Now I want to login via Facebook, I end up on the Facebook login page, I enter my credentials, and... nothing!
I end up back on my homepage, not logged in, no log messages that mean anything to me, just silence. The last thing I see in the log is:
Getting user info from: https://graph.facebook.com/me

This Url will give me in my browser:

{
   "error": {
      "message": "An active access token must be used to query information about the current user.",
      "type": "OAuthException",
      "code": 2500,
      "fbtrace_id": "GV/58H5f4fJ"
   }
}

When going to this URL via an IntelliJ start, it will give me credential details. Obviously something is going wrong, but I have no clue what. Especially since a run from IntelliJ works fine. There is some difference between how the jar is started, and how IntelliJ's run config works, but I have no clue where to search for what. I could post trace logging, or all my Gradle files, but perhaps thats too much info to put in 1 question. I will defenitly update this question if someone needs some more details :)

The structure outline of this project is as follows:

root:
  - api: is going to be opensourced later, contains rest definitions and DTOs.
  - core: contains the meat. Also here is included in the gradle file
             spring-boot-starter, -web, -security, spring-security-oauth2, and some jackson stuff.
  - rest: contains versioned rest service implementations.
  - app: contains angular webjars amongst others, the front end, and 
             my `@SpringBootApplication`, `@EnableOAuth2Client` 
             and the impl of `WebSecurityConfigurerAdapter`.

Why does everything run fine when started via IntelliJ, and why is it broken using bootRun or the jar artefact. And how do I fix this?

1

There are 1 best solutions below

0
On BEST ANSWER

I found it, the problem was not Multi module Graldle, Spring boot, or Oauth2 related. In fact it was due to a src set config of Gradle, where Java was supposed to be in a Java src set folder, and Kotlin in a Java src set folder:

sourceSets {
    main.java.srcDirs += 'src/main/java'
    main.kotlin.srcDirs += 'src/main/kotlin'
}

As Will Humphreys stated in his comment above, IntelliJ takes all source sets, and runs the app. However, when building the jar via Gradle, these source sets are stricter. I had a Java file in my Kotlin src set, which is no problem for IntelliJ. But the jar created by Gradle takes into account the source sets as defined in the build.gralde file, which are stricter.

I found my missing bean issue with the code below:

@Bean
public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
    return args -> {
        System.out.println("Let's inspect the beans provided by Spring Boot:");

        String[] beanNames = ctx.getBeanDefinitionNames();
        Arrays.sort(beanNames);
        for (String beanName : beanNames) {
            System.out.println(beanName);
        }

    };
}

The Bean I missed was called AuthenticationController, which is a @RestController, and kinda crucial for my authentication code.