4

So I am playing around with Spring and Java 10 along with Gradle.

In my application, I created 2 modules

  • UI
  • Application

The application module's gradle file looks like this

dependencies {
    compile project (':ui')
}

And module-info file looks like this

module application {
    requires spring.context;
    requires spring.boot.autoconfigure;
    requires spring.boot;
}

In my UI module, the build.gradle looks like this

dependencies {
    compile('com.vaadin:vaadin-spring-boot-starter')
}

dependencyManagement {
    imports {
        mavenBom "com.vaadin:vaadin-bom:${vaadinVersion}"
    }
}

And module-info looks like this

module ui {
    requires vaadin.server;
    requires vaadin.spring;
}

So my UI code lives inside ui module. As you can see, I am not exporting any package outside from the ui module and application's module-info also doesn't require ui.

In the main class I added

@ComponentScan("com.factory_manager")

And magically it's able to scan the UI module and the vaadin UI classes and I am able to access them via their respective endpoints.

From my understanding, the application module should not be able to read ui module's classes as I am not exporting any package outside.

Does anyone has any idea on how spring is magically able to scan the ui module and find the ui classes?

And yes, I am unable to access UI module's classes inside my application module but spring somehow is able to..

Sneh
  • 3,527
  • 2
  • 19
  • 37

1 Answers1

2

Not very gradle specific, yet a probable reason for this could be your dependency code -

dependencies {
    compile project (':ui')
} 

Due to which the ui module classes are present on the classpath instead of the module path and are under the unnamed module.

To correlate further, the unnamed module exports all of its packages and hence you're able to access those classes without exporting them.

Top of my mind, one way you can confirm this is, by trying out something like -

<yourClassFromUIModule>.class.getModule().isNamed(); //should return false
Naman
  • 27,789
  • 26
  • 218
  • 353
  • I tried to remove dependency on ui project. Then I added the relevant export in ui module-info. Problem is that if I want to add requires ui, in my application module's module-info then I need gradle dependency on ui in my application's build.gradle file :S.. – Sneh Aug 22 '18 at 19:19
  • @Sneh If you need the dependency, you certainly need it in the gradle. The difference is in the presence of that dependency on the classpath versus on the modulepath. – Naman Aug 22 '18 at 19:23
  • 1
    @Sneh See [Building Java 9 Modules (in Gradle)](https://guides.gradle.org/building-java-9-modules/). – Slaw Aug 22 '18 at 19:26
  • Hmm I think I am getting it now. Spring is able to scan it because it is present in the classpath of application module. – Sneh Aug 22 '18 at 19:27
  • Thanks @Slaw, will check it out. – Sneh Aug 22 '18 at 19:27
  • @nullpointer as far as I understand, the piece of code won't help me becsause to be able to access the class, I will need to export it and then require it, which will then end up putting it in a "named" module. – Sneh Aug 22 '18 at 19:29
  • Ahh wait, it doesn't make any sense.. It returns me false even after having a requires on ui module and exporting the package. I will investigate more. Thanks for the help. – Sneh Aug 22 '18 at 19:31
  • I did more investigation and somehow suddenly without any code change `.class.getModule().isNamed(); ` is returning true. And spring is unable to load the class without me adding a requires ui... – Sneh Aug 29 '18 at 13:30
  • @Sneh both of us know, it cannot be just something sudden. Would suggest looking at the [modules resolved while you start your application.](https://stackoverflow.com/questions/48339598/list-the-modules-resolved-during-the-application-startup) – Naman Aug 29 '18 at 14:08
  • Yep, I completely agree with you @nullpointer. I think it might have to do with gradle versions. I will look into it further. Thanks. – Sneh Aug 29 '18 at 15:41