-
Notifications
You must be signed in to change notification settings - Fork 144
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve application-specific libraries loading #24946
Improve application-specific libraries loading #24946
Conversation
8655697
to
e86d740
Compare
@dmatej, what do you think about the concept itself? |
...eus/core/kernel/src/main/java/com/sun/enterprise/v3/server/AppLibClassLoaderServiceImpl.java
Outdated
Show resolved
Hide resolved
cbf7e0b
to
f5e04c2
Compare
f5e04c2
to
48a9874
Compare
Main part is done. Only minor changes need to be made. What you think, @dmatej? |
a995ce9
to
5342b80
Compare
Signed-off-by: Alexander Pinčuk <alexander.v.pinchuk@gmail.com>
5342b80
to
c2c3762
Compare
Signed-off-by: Alexander Pinčuk <alexander.v.pinchuk@gmail.com>
Signed-off-by: Alexander Pinčuk <alexander.v.pinchuk@gmail.com>
Signed-off-by: Alexander Pinčuk <alexander.v.pinchuk@gmail.com>
Signed-off-by: Alexander Pinčuk <alexander.v.pinchuk@gmail.com>
ce38f70
to
21a7ca4
Compare
Signed-off-by: Alexander Pinčuk <alexander.v.pinchuk@gmail.com>
I will try before the end of the week, now I am struggling with some network issues and I am several days behind my email notifications ... |
Method method; | ||
Field field; | ||
try { | ||
if (OS.isWindows()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't there already a way how to get these with NIO? Maybe just with newer JDK versions, I am not sure now. I have to check it later ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't there already a way how to get these with NIO? Maybe just with newer JDK versions, I am not sure now. I have to check it later ...
I just need to add logging and do some code cleanup... After that, I will add a detailed description of why the decision was made to use certain platform-dependent means.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem is that it may change or even be abandoned in the future. How critical is the difference from this? https://www.baeldung.com/java-nio2-file-attribute
Is this the whole explanation?
If we are unable to create a temporary snapshot of the library using native descriptor, we fall back to using standard NIO.2 functions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem is that it may change or even be abandoned in the future. How critical is the difference from this? https://www.baeldung.com/java-nio2-file-attribute
This prevents inconsistency between file attributes and library content in case where library has been replaced with new one after the attributes were read, but before the snapshot was created.
First, I open FileInputStream
. This block the file from being replaced or deleted on Windows and saves the contents of the file (inode?) on UNIX until the input stream closes. Then I get the open file descriptor (handle on Windows) and read the attributes from it. Then I copy the open input stream to a temporary file and close input stream. This ensures that the attributes match the file exactly.
If for some reason it is impossible to read attributes using os-dependent functions, we return to using standard NIO.2 functions (as described in the Baeldung article).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it may change or even be abandoned in the future
In this case snandard NIO.2 will be used. Maybe until another solution is found.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did tests on Temurin 11-22 and some latest Semeru.
I also tried using simple tests how to get the attributes of open files on Windows, Linux, macOS and Solaris(OpenIndiana). For OpenJDK-derived JVMs from 11 to 22 all works now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It still smells to me as some bad practice, but ok, lets try that, if somebody finds it problematic in practice, I hope he will report it. Maybe it would be worth to create an issue for JDK to "open these doors".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It still smells to me as some bad practice
Unfortunately, Java doesn't have methods FileInputStream.getAttibutes()
, FileChannel.getAttributes()
, Files.readAttributes(FileDescriptor fd, ...)
or similar. Therefore we are forced to use the "reflection magic".
lets try that, if somebody finds it problematic in practice, I hope he will report it
This should never fail. If "reflection magic" does not work, the standard path will:
// Fallback to the standard NIO.2 method
if (attributes == null) {
attributes = readAttributes(libURI);
}
In readAttributes() method
return Files.readAttributes(Path.of(libURI), BasicFileAttributes.class);
Signed-off-by: Alexander Pinčuk <alexander.v.pinchuk@gmail.com>
Signed-off-by: Alexander Pinčuk <alexander.v.pinchuk@gmail.com>
Signed-off-by: Alexander Pinčuk <alexander.v.pinchuk@gmail.com>
Signed-off-by: Alexander Pinčuk <alexander.v.pinchuk@gmail.com>
Signed-off-by: Alexander Pinčuk <alexander.v.pinchuk@gmail.com>
Signed-off-by: Alexander Pinčuk <alexander.v.pinchuk@gmail.com>
Signed-off-by: Alexander Pinčuk <alexander.v.pinchuk@gmail.com>
Signed-off-by: Alexander Pinčuk <alexander.v.pinchuk@gmail.com>
Tested on Ubuntu 22.04.4 LTS, Windows 10 22H2 and macOS 14.5. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. That snapshots is needed to troubleshoot app problems, but I'm not sure if the system's temp directory is the best place for it.
Thank you for reply! I thought about it, but I don't know where the right place is. Any suggestions? |
Humm... there are several candidates...
The
|
Signed-off-by: Alexander Pinčuk <alexander.v.pinchuk@gmail.com>
Signed-off-by: Alexander Pinčuk <alexander.v.pinchuk@gmail.com>
Signed-off-by: Alexander Pinčuk <alexander.v.pinchuk@gmail.com>
Signed-off-by: Alexander Pinčuk <alexander.v.pinchuk@gmail.com>
There's cons and pros to system tmp and domain/[somewhere]. System tmp gets cleaned automatically, at some point. The con is that the connection between the usage of the tmp folder and the using application is less clear. Lots of other tmp stuff is put inside the GF folders now, like e.g. all the generated java code for Pages (JSP). |
To the temporary dir - on linux user can use soft link and link it to the operating system. However I don't remember how it would affect replications in cluster - and also if it should affect them. |
Snapshots are excluded from replication. Replication of an original libraries left unchanged. |
LGTM now. If anything needs to be enhanced still, let's do it in a follow-up PR. |
You should wait a bit until we finish the discussion. Now I cannot add my approval and two years later I might argue I did not approve it :D Btw all tests including TCK I have on my Jenkins passed two hours ago, so I would approve it now. So I do that at least as a comment. |
When Jakarta EE applications and modules use shared framework classes (such as utility classes and libraries), the classes can be put in the path for an application-specific class loader rather than in an application or module.
Application libraries are included in the AppLib class loader.
If multiple applications or modules refer to the same libraries, classes in those libraries are automatically shared.
Since these libraries are external to applications and the GlassFish server itself, they can be deleted or replaced with new versions using operating system tools. The result is system dependent.
It is necessary to make the behavior of application libraries the same on all supported platforms.
The proposed solution attempts to achive this by creating temporary snapshots of the application libraries during application startup.
An application library is identified by its
URI
and some set of basic file attributes (size
,lastModifiedTime
andfileKey
). If a library with the same URI and attributes is already loaded, use it. If not, load it and put in the registry of loaded application libraries for reuse by other applications.First we try to create a temporary snapshot of the application library:
FileInputStream
, get the native open file descriptor from it and read its basic file attributes.Performing these steps ensures that the file attributes match exactly the library content. This gives us some degree of atomicity.
A discrepancy is possible, for example, in the following scenario:
In this case basic fie attributes will not match the library.
If we are unable to create a temporary snapshot of the library using native descriptor, we fall back to using standard NIO.2 functions.
If we cannot create a snapshot of the library for some reason, we fall back to using the original library.
Last but not least, we close application libraries class loaders and delete snapshots when the GlassFish server is stopped.