#Reflection in Java 8 and Java 17

1 messages · Page 1 of 1 (latest)

hallow rune
#

hi, I have some Reflection code from Java 8 that works fine but with Java 17 it breaks

old ospreyBOT
#

<@&987246399047479336> please have a look, thanks.

old ospreyBOT
#

While you are waiting for getting help, here are some tips to improve your experience:

Code is much easier to read if posted with syntax highlighting and proper formatting.

If nobody is calling back, that usually means that your question was not well asked and hence nobody feels confident enough answering. Try to use your time to elaborate, provide details, context, more code, examples and maybe some screenshots. With enough info, someone knows the answer for sure.

Don't forget to close your thread using the command </help-thread close:1027500463647621170> when your question has been answered, thanks.

hallow rune
#

the code is the following ```java

public static void enable(String... methods) throws NoSuchFieldException, IllegalAccessException {
    Field declaredFieldMethods = HttpURLConnection.class.getDeclaredField("methods");
    Field declaredFieldModifiers = Field.class.getDeclaredField("modifiers");
    declaredFieldModifiers.setAccessible(true);
    declaredFieldModifiers.setInt(declaredFieldMethods, declaredFieldMethods.getModifiers() & ~Modifier.FINAL);
    declaredFieldMethods.setAccessible(true);
    String[] previous = (String[]) declaredFieldMethods.get(null);
    Set<String> current = new LinkedHashSet<>(Arrays.asList(previous));
    current.addAll(Arrays.asList(methods));
    String[] patched = current.toArray(new String[0]);
    declaredFieldMethods.set(null, patched);
}
old ospreyBOT
hallow rune
#

I cant find alot regarding Java 17, but its something that should also apparently not be working in Java 8

#

some answers on a Stackoverflow where pointing towards Constructor.setAccessible(true) but I am not sure if this is accucare, I tried playing around a bit but I am unsure which Constructor I am ment to modify

#

I tried to add this at the top of my method java Constructor<?>[] constructors = Field.class.getDeclaredConstructors(); for (Constructor<?> constructor : constructors) { constructor.setAccessible(true); } but this just errors aswell saying Unable to make java.lang.reflect.Field(java.lang.Class,java.lang.String,java.lang.Class,int,boolean,int,java.lang.String,byte[]) accessible: module java.base does not "opens java.lang.reflect" to unnamed module @7106e68e

old ospreyBOT
hallow rune
wary pilot
hallow rune
#

its just compatibility for Java 17+ because there is no PATCH and OPTIONS in the HttpUrlConnection class for allowed HTTP methods

#

I read that it should be able to work if done properly but I cant figure the properly out

wary pilot
#

why are you trying to access Field constructor ?

hallow rune
#

I dont want to access any constructor I want to add two String to this array

#

I just read that for Java 17 I am supposed todo something with Constructors to get access to the Fields

wary pilot
wary pilot
#

yes

#

you are trying to access Field's constructor

#

why would you want to do that

hallow rune
#

thats what I tried to add because on the Stackoverflow I linked they were talking about Constructor.setAccessible

wary pilot
#

this code is unrelated to what your problem seems to be

hallow rune
#

oh

#

then that was my mistake

wary pilot
#

I am repeating, you are trying to access the constructor of the class Field

#

why are you trying to do that ?

hallow rune
#

well it doesnt really make sense for me to access the Field class Constructor because the field I want to modify is in HttpURLConneciton

#

I was just trying to make something work from reading those comments

wary pilot
#

right so

#

how are you creating the HttpURLConnection ?

hallow rune
#

doing the same for HttpURLConnection is giving the same error, assuming its still because of --add-open, I did add that as args though

#

in which context, for reflection or how its used within my code

#

within my code its would be
(HttpsURLConnection) URL(String).openConnection()

#

I am aware this it Https*

wary pilot
#

so

#

instead of that

#

you should use HttpClient and HttpRequest

hallow rune
#

but thats not available in Java 8

#

thats 11

wary pilot
#

but that's available in java 17

hallow rune
#

yeah but I just want to add something so people running Java 17 wont Crash on startup

wary pilot
#

can't you just update to java 17 ?

hallow rune
#

well technically I could but alot of the people run different Versions and most of them are still on Java 8

#

I thought some extra lines to the reflection could make it work

wary pilot
hallow rune
#

the --add-open ?

wary pilot
hallow rune
#

mhm I added that though or is there a specific way to put it

wary pilot
#

but note that it might be removed at some point

hallow rune
#

well in theory if its not fixable within my own code I will just make the minimum requirement Java 11 for HttpClient

#

because that supports Patch & OPTIONS

wary pilot
# hallow rune

should be something in the lines of --add-opens java.base/java.lang=ALL-UNNAMED

hallow rune
wary pilot
hallow rune
#

I know, even HTTP2 🥹

wary pilot
#

also

#

is it an app ?

#

or a lib ?

hallow rune
#

yes its some proxy server for a game that allows you to see internal traffic

wary pilot
#

because if it is an app, you should provide the jre to customers

hallow rune
#

and one of the first requests is a PATCH

wary pilot
hallow rune
#

like bundle the jre in?

#

I read about that once but never figured out how todo that

wary pilot
hallow rune
#

it would only include the classes that are required to run aswell from what I remember

#

I really liked it but never got it to work

wary pilot
#

you can use tools like jpackage to create an installer

#

and then you give this installer

hallow rune
#

I'll take a look now, and try to get it working myself - I will fall back to this Thread if I run into issues

#

I am a bit smarter than I was when I first tried it so I hope I can manage

old ospreyBOT
#

Due to the JVM and bytecode as intermediate execution stage, turning a Java application into a standalone executable (exe, msi, deb, rpm, dmg, pkg) is not trivial.
However, there exist various tools to do the job. They mostly differ in the details of the solution they create and hence also in their purpose:

  • jpackage (the official tool) - creates an installer
  • Launch4J - creates a wrapper executable that unwraps on execution
  • GraalVM - attempts to create an actual native executable instead of wrappers or installers

This guide explains how to use jpackage, an official tool that is available in all JDKs since Java 16. The tool creates an installer for the application, so the end-user will get an executable that guides them through a setup where they can select installation path and tweak other settings, finally resulting in the application being installed on the machine (with a proper uninstaller, desktop shortcuts, start menu entries, ...): https://i.imgur.com/2V5ovUu.png

As an example, suppose you have a fat jar of your application called HelloWorld.jar, with a main class called Main. Put the jar into a dedicated release folder for simplicity. Execute the following command and you have an installer for your application in a folder called installer:

jpackage --input "release" --dest "installer" --main-class "Main" --main-jar "HelloWorld.jar" --name "HelloWorld" --win-dir-chooser --win-menu --win-shortcut --type exe

See the official documentation for more information on the available commands and for other operating systems:

Here is an example for a more complex setup which also associates file endings to the application, has a custom icon and more: https://pastebin.com/cfzqSKnW

hallow rune
#

lovely thanks, I'll read now

#

well given jpackage ships at Java 16, I assume I can fallback to Launch4J for Java 8

wary pilot
hallow rune
#

ah wait true

#

it doesnt matter which Version anyone has installed

#

my brain wasnt functioning

#

I forgot thats the whole point behind this

calm nimbus
hallow rune
#

ugh

#

I have Java 11/17/19 installed but I removed all Path variables

#

I remember it wasnt JAVA_HOME for some higher versions

#

guess I just reinstall 17

#

ah its not setting the Path variables for 17

ebon oak
#

you don't need to reinstall

#

just to set the path variable

hallow rune
#

I remember there was more than just JAVA_HOME for 17

#

but i dont remember what it was called

#

thats why I wanted to reinstall

ebon oak
#

There is also Path

#

where you go into the bin folder and paste it there

#

Il show you

hallow rune
#

is JAVA_HOME supposed to point to the jdk folder or the bin

ebon oak
#

jdk folder

#

and the Path to the bin

#

like C:\Program Files\Java\jdk-17.0.3.1\bin for path

hallow rune
#

am i missing something

#

java -version still gives 8 after restarting cmd

#

ah Path in System

#

OKAY thank you

ebon oak
#

np

hallow rune
#

[16:46:55.355] Can not find WiX tools (light.exe, candle.exe)
[16:46:55.355] Download WiX 3.0 or later from https://wixtoolset.org and add it to the PATH.
Error: Invalid or unsupported type: [exe]

do I just jam the wix exe into my jdk17 folder

The most powerful set of tools available to create your Windows installation experience.

#

or is there some convetion of where to put things like this

ebon oak
#

why not install wix into a seperate folder like all your applications?

hallow rune
#

i dont have to install it it just needs the exe

#

Ill make a folder in appdata for it

#

atleast I think I dont have to install yet I'll see

#

ok nvm

#

i had to install it

#

oh this is so cool

#

just turned from 400kb jar to 48mb exe but I guess thats how it is

#

or is there a way to optimize this exe somehow

wary pilot
# hallow rune

you should remove the path to java 17 here and only keep a path to JAVA_HOME

wary pilot
#

with jpackage and jlink you should be able to tell it to remove unused modules

#

but that's all

#

you could try graalvm I guess, maybe

hallow rune
#

since this is an installer how does versioning work

#

lets assume i release an exe and then update it a week later

#

would it be installed as a seperate program or does it overwrite the previous

#

actually I assume itll overwrite

#

so I tested jpackage with one of my other tools and it ran fine using jpackage --input "release" --dest "installer" --main-class "Main" --main-jar .\Mundo-1.101-jar-with-dependencies.jar --name "HelloWorld" --win-dir-chooser --win-menu --win-shortcut --type exe

#

I installed it using the exe

#

but nothing happens when running the Mundo.exe now, the original jar is in the app directory and works fine

#

theres no error anywhere either

hallow rune
#

tried to make another installer using the same command, the installer just errors and insta closes, cant even see anything

#

well.. seems like this might be an issue

hallow rune
#

if I uninstall Mundo properly the installer works again

#

so I have two issues now:
• installed exe does nothing
• unable to launch a new installer (instantly errors)

tidal fossil
#

Check what it fails on, is there no error code or log

hallow rune
#

theres nothing

#

the exe just closes