17

I have an OSGI application and I have around 30 bundles (jar files). Today I decided to see how it works/if it works with Java 9.

So I started my application and got

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.apache.felix.framework.util.SecureAction (file:/home/.../jar/org.apache.felix.framework-5.4.0.jar) to method java.net.URLClassLoader.addURL(java.net.URL)
WARNING: Please consider reporting this to the maintainers of org.apache.felix.framework.util.SecureAction
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

After some reading I added command line option

--add-exports java.base/java.net=org.apache.felix.framework 

and created file module-info.java with the following content:

module org.apache.felix.framework { }

And I have two questions. Where should I place this module-info.java to make jvm read it? How should I bind this module-info with org.apache.felix.framework-5.4.0.jar file/bundle/jar?

If I do everything wrong please, show me right direction for fixing this problem.

Pavel_K
  • 10,748
  • 13
  • 73
  • 186
  • 1
    This may not merit an answer but in case it helps, [here](https://github.com/codetojoy/WarO_Java_9/blob/master/List.md) is a small example in Java 9. See link for a version of it in OSGi (Java 8). – Michael Easter Sep 06 '17 at 10:35

3 Answers3

21

Generic tips:

To answer your specific questions:

Place module declaration (module-info.java) into the project's source root directory (e.g. src/main/java). It must be among the list of files to compile to be turned into a module descriptor (module-info.class). Last step is to include it in the list of class files that are packaged into a JAR. Having a module descriptor in a JAR turns it into a modular JAR. If placed on the module path, the JPMS turns it into a module.

If you don't want to create modules after all and prefer your code to run in the unnamed module, you can allow it to access internal APIs with the placeholder ALL-UNNAMED - in the case f your warning you need to open that package to reflection:

--add-opens java.base/java.net=ALL-UNNAMED

The better solution would be to stop using internal APIs, though. As this is not your code, but your dependency, you should look for or open an issue with Apache Felix that asks to remove the access of internal API.

Dave Jarvis
  • 30,436
  • 41
  • 178
  • 315
Nicolai Parlog
  • 47,972
  • 24
  • 125
  • 255
  • Thank you. Ok, I don't want to create any modules, I want them to be unnamed. But how then should I solve `WARNING: An illegal reflective access operation has occurred` problem? – Pavel_K Sep 05 '17 at 21:26
  • 1
    Updated the answer to include `ALL-UNNAMED`. – Nicolai Parlog Sep 05 '17 at 21:52
  • Thank you very much, but `-add-exports java.base/java.net=ALL-UNNAMED` and `--add-exports java.base/java.net=ALL-UNNAMED` didn't help. I get the same error. – Pavel_K Sep 05 '17 at 22:22
  • 1
    Yes, sorry, I didn't look at your log closely enough. By the way, it's "just" a warning, not an error. – Nicolai Parlog Sep 05 '17 at 22:57
  • Thank you very much again. However, if I add `--add-opens java.base/java.net ALL-UNNAMED` then I get `java.lang.RuntimeException: Unable to parse --add-opens =: java.base/java.net`. If I add `--add-opens java.base/java.net=ALL-UNNAMED` I get the same error. How to fix it? Sorry for asking again. – Pavel_K Sep 06 '17 at 07:02
  • 1
    @Pavel_K Apparently it was a little late yesterday. Yes, you need the `=` in there (corrected the answer), but then it should work (it does for me). – Nicolai Parlog Sep 06 '17 at 09:48
  • @Nicolai When putting the module-info.java into src/main/java the potentially used src/main/recources is not on the module path. Is it ok to move it to src/main then? – SixDoubleFiveTreeTwoOne Nov 29 '17 at 13:27
3

Well the Jigsaw quick start is a nice way to start off with if you're kick starting a project on Java-9.

Where should I place this module-info.java to make jvm read it?

Inferring your module name from the declaration module org.apache.felix.framework { }, you should place the module-info.java file in your project directory at:

src/org.apache.felix.framework/module-info.java 

How should I bind this module-info with org.apache.felix.framework-5.4.0.jar file/bundle/jar?

Further to compile modules and package them(bind the module-info.class at the top level directory of your modular jar), you can use the javac and jar commands.

Sample commands for the above would be somewhat like :

$ javac --module-path mods -d mods/org.apache.felix.framework \
    src/org.apache.felix.framework/module-info.java src/org.apache.felix.framework/com/apache/felix/framework/Application.java


$ jar --create --file=mlib/org.apache.felix.framework.jar \
    --main-class=com.apache.felix.framework.Application -C mods/com.apache.felix.framework

And further you can execute the module using:

$ java -p mlib -m com.apache.felix.framework

Also apart from The State Module System and the Quick-Start documents, for migrating existing projects to Java-9, I would suggest you to follow the JDK9 Migration Guide which states a clear step wise transition required to adapt to Java9.

samabcde
  • 6,988
  • 2
  • 25
  • 41
Naman
  • 27,789
  • 26
  • 218
  • 353
3

You should submit a bug to Apache Felix as it's the code in org.apache.felix.framework-5.4.0.jar that is doing the illegal access and needs to be fixed. I did a quick test with newer version 5.6.8 and with --illegal-access=debug and it appears that Felix has several issues that need attention. Yes, you can temporarily eliminate the specific warning above by opening the java.net package to "ALL-UNNAMED" but that is just one or many issues.

Alan Bateman
  • 5,283
  • 1
  • 20
  • 25