Skip to content

Conversation

@tanya011
Copy link

@tanya011 tanya011 commented Nov 6, 2024

  • java-atk-wrapper used to be part of OpenJDK (JDK-8204862, IJPL-136231), but it was removed.
  • java-atk-wrapper is essential for accessibility in Java applications, including IntelliJ IDEA: IJPL-58438, JBR-4578.
  • AccessibleAnnouncerTest.java test is passed.
  • java-atk-wrapper has an LGPL 2.1 license, which can be up-cast to GPL-2.0, allowing the source code to be used.

@OnePatchGuy OnePatchGuy self-requested a review November 6, 2024 13:45
@tanya011 tanya011 force-pushed the jbr21 branch 3 times, most recently from 4af7c31 to 081ca50 Compare November 19, 2024 16:56
@vprovodin
Copy link
Collaborator

All changes in JBR should be accompanied with tickets in YT related to the JBR project. Ticket-id should be placed at the beginning of the commit message. Within this JBR ticket we may make proper changes in docker files. Please note the libraries you aded to docker files actually are not available for Oracle Linux 8 that is build platform for jbr21.

@tanya011 tanya011 changed the title IJPL-58438 Add Java ATK Wrapper JBR-4578 Add Java ATK Wrapper Nov 28, 2024
@tanya011 tanya011 force-pushed the jbr21 branch 2 times, most recently from 1d350f8 to 3fc3625 Compare December 18, 2024 16:15
Copy link
Member

@OnePatchGuy OnePatchGuy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the patch! It's been a hard work, hasn't it? :)

I've done reviewing only the changes in the build scripts (everything under the make directory). All the questions and suggestions are below. Reviewing the rest is coming.

From now on, please don't rewrite the commits history so that I'll be able to observe only the changed parts in newly added commits (we'll later squash them during merging).

Comment on lines 123 to 127
NEEDS_LIB_ATK=true
NEEDS_LIB_AT_SPI2_ATK=true
NEEDS_LIB_GLIB=true
NEEDS_LIB_GOBJECT=true
NEEDS_LIB_GLIBCONFIG=true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The patch adds new build-time dependencies, but:

  1. Our CI doesn't respect them (yet), thus if we merge the patch as is, it'll immediately get broken. E.g. what I get if I try to make a build in a docker container as described in the README:

Package atspi-2 was not found in the pkg-config search path.
Perhaps you should add the directory containing 'atspi-2.pc'
to the PKG_CONFIG_PATH environment variable
Package 'atspi-2', required by 'virtual:world', not found
Creating support/modules_libs/jdk.accessibility/libatk-wrapper.so from 16 file(s)
/JetBrainsRuntime/src/jdk.accessibility/linux/native/libatk-wrapper/AtkWrapper.c:25:10: fatal error: glib.h: No such > file or directory
#include <glib.h>
^~~~~~~~
compilation terminated.

(I get the same on Ubuntu 22 before installing the dependencies).

I can suggest 2 following ways of solving the problem:

  • to make the corresponding changes to our build scripts, docker images, etc. and include them into this PR ;
  • to make the changes provided in this patch disabled by default (i.e. apply --disable-java-atk-wrapper by default) and deal with all this CI stuff later after merging the patch .

Anyway, please note @vprovodin noticed earlier that Oracle Linux 8 which we're using as a build platform (via a docker image) doesn't provide these new dependencies, so it may become a serious obstacle for this patch.

  1. The build instructions in README haven't been updated correspondingly.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The build instructions in README haven't been updated correspondingly.

I updated README, but not sure where to locate build instructions

Copy link
Member

@OnePatchGuy OnePatchGuy Jan 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure where to locate build instructions

Our README is currently describing 2 ways of how to build a JBR for Linux:

  • Using a specially designed docker container - the chapter Linux (Docker)
  • Using an Ubuntu as a host system - the chapter Ubuntu Linux

For now there's probably nothing to change in the Docker chapter, but Ubuntu chapter should be supplemented with the new packages and instructions how to enable/disable ATK wrapper and how to pass custom paths to it. Examples could be Windows's chapters Enable optional NVDA screen reader support and Disable optional JAWS screen reader support.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done at f83061c

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.
Let's file an issue about fixing CI and enabling back the patch by default and we can close this thread :).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a note: here seems the full list of Ubuntu 22 packages that must be additionally installed to build the patch:

  • libatspi2.0-dev
  • libatk1.0-dev
  • libglib2.0-dev
  • libatk-bridge2.0-dev

-DATSPI_MINOR_VERSION=$(shell pkg-config --modversion atspi-2 | cut -d. -f2) \
-DATSPI_MICRO_VERSION=$(shell pkg-config --modversion atspi-2 | cut -d. -f3), \
LDFLAGS := $(LDFLAGS_JDKLIB), \
LIBS_linux := -ljvm $(ATK_LIBS) $(AT_SPI2_ATK_LIBS) $(GLIB_LIBS) $(GOBJECT_LIBS), \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding -ljava and/or -lawt as well if needed (I don't know).

@OnePatchGuy
Copy link
Member

OnePatchGuy commented Jan 15, 2025

My main question about the entire patch is the following: as you've written in the description, this functionality was removed some time ago due to a lot of bugs mentioned in e.g. IJPL-136231:

The problem is that the tool breaks the Swing threading rule and causes lots of exceptions & UI artefacts

and in JBR-4578:

Important! ATKWrapper contains bugs that can crash the JBR.

Also known issues:

  • Lists with complex renders work slowly;
  • Tree nodes are not voiced;
  • comboboxes are not spoken.

All these problems must be solved directly in ATKWrapper.

By putting all this logic back, do you state that all those problems have been fixed and now AWT wrapper is in production-ready quality?

UPD: still actual crash https://discourse.gnome.org/t/sigsegv-in-g-type-check-instance-is-fundamentally-a-0x11/24285

Copy link
Member

@OnePatchGuy OnePatchGuy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I seem to have done reviewing everything related to the Wrapper initialization.
Besides that, this "round" also contains a few comments about the resource management and some general notes.

@OnePatchGuy
Copy link
Member

BTW, I think each file that gets updated should also have its copyright header updated. One of the most recent examples of our header can be found e.g. in https://github.com/JetBrains/JetBrainsRuntime/blob/f89a6626d56dad71c3429c662bdad89f6b9a0591/src/java.desktop/unix/classes/sun/awt/wl/WLDisplay.java, but I don't know how to properly merge the existing headers with our one.

@tanya011 tanya011 requested a review from OnePatchGuy February 11, 2025 08:29
Copy link
Member

@OnePatchGuy OnePatchGuy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have finished reviewing the rest of the initial code. Have found a lot of issues, some of them are critical memory leaks or, in opposite, use-after-free errors

private static void initializeMap() {
keyMap = new HashMap<>(146); // Currently only 110, so allocate 110 / 0.75

keyMap.put(Integer.valueOf(KeyEvent.VK_COLON), new GNOMEKeyInfo(0x20a1, "ColonSign")); // GDK_ColonSign
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[refactoring] There are lots of meaningless integer boxing in this file, let's get rid of them.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

@OnePatchGuy OnePatchGuy May 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One is left at line 197

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done 6ac03ba

break;
}
default: {
char[] chars = new char[1];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use String.valueOf(char) instead

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect. Now an integer gets converted to a string, check the difference: https://www.programiz.com/online-compiler/8tH16xnBdMlKT

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed cb05563

* even been sent!
*/
static pthread_mutex_t jaw_vdc_dup_mutex = PTHREAD_MUTEX_INITIALIZER;
static jobject jaw_vdc_last_ac = NULL;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are the usages of this variable implemented correctly?

  1. Comparisons to other JNI references are performed through "raw" pointer comparisons, although different JNI references may reference the same Java object.
  2. It gets assigned to local JNI reference which are only valid during a JNI downcall.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done 1fb4bb8

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now it gets assigned to NewGlobalRef but ReleaseGlobalRef is never applied to it.

Comment on lines 191 to 215
enum _SignalType {
Sig_Text_Caret_Moved = 0,
Sig_Text_Property_Changed_Insert = 1,
Sig_Text_Property_Changed_Delete = 2,
Sig_Text_Property_Changed_Replace = 3,
Sig_Object_Children_Changed_Add = 4,
Sig_Object_Children_Changed_Remove = 5,
Sig_Object_Active_Descendant_Changed = 6,
Sig_Object_Selection_Changed = 7,
Sig_Object_Visible_Data_Changed = 8,
Sig_Object_Property_Change_Accessible_Actions = 9,
Sig_Object_Property_Change_Accessible_Value = 10,
Sig_Object_Property_Change_Accessible_Description = 11,
Sig_Object_Property_Change_Accessible_Name = 12,
Sig_Object_Property_Change_Accessible_Hypertext_Offset = 13,
Sig_Object_Property_Change_Accessible_Table_Caption = 14,
Sig_Object_Property_Change_Accessible_Table_Summary = 15,
Sig_Object_Property_Change_Accessible_Table_Column_Header = 16,
Sig_Object_Property_Change_Accessible_Table_Column_Description = 17,
Sig_Object_Property_Change_Accessible_Table_Row_Header = 18,
Sig_Object_Property_Change_Accessible_Table_Row_Description = 19,
Sig_Table_Model_Changed = 20,
Sig_Text_Property_Changed = 21
};

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This enum is just a copy of AtkSignal.java. If you mark the constants from there with @Native annotation, they can be reused directly in native code (a native header org_GNOME_Accessibility_AtkSignal.h will be generated), thus avoiding the duplications.

Please also check all other native and Java enums for duplicates.

Copy link
Author

@tanya011 tanya011 Mar 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done 16166eb, and I renamed org_GNOME_Accessibility_AtkSignal.h to AtkSignal.h later. See src/jdk.accessibility/linux/native/libatk-wrapper/AtkSignal.h

AtkInterface: f4d4c23

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The generated headers shouldn't be stored - they automatically get generated and integrated with the build system each time the project gets built. You just need to include such a header e.g.

#include "org_GNOME_Accessibility_AtkSignal.h"

to get access to the constants defined in the interface org.GNOME.Accessibility.AtkSignal.

So please remove all those committed headers.

The same situation is for AtkWrapper.h - just including org_GNOME_Accessibility_AtkWrapper.h instead will do the trick.

Copy link
Member

@OnePatchGuy OnePatchGuy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have reviewed the recent updates.

private static final Object lock = new Object();
private static AtkWrapperDisposer disposerInstance;

static {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's convert the class to a lazy initialized singleton, so that threads will be created only when required and not when the class is getting loaded.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done c709d8c

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since now we check INSTANCE for null outside of the synchronized block, let's mark it volatile.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done 63aae9b

Copy link
Member

@OnePatchGuy OnePatchGuy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forgot to comment one piece.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants