Ingeniería y evidencia

Tickets de JetBrains Platform

Errores en el propio código de JetBrains, documentados públicamente en su tracker YouTrack: seis presentados directamente, cuatro encontrados en el código de IntelliJ por un control de este catálogo o un escaneo relacionado y dos al medir las páginas de Settings en el hilo de interfaz, más análisis de causa raíz publicados en tickets existentes de IntelliJ Platform (IJPL) y dos arreglos enviados como pull requests.

Presentado directamente

Errores encontrados en el propio código de IntelliJ por un control de este catálogo o midiendo el hilo de interfaz del IDE, y luego reportados a JetBrains.

IDEA-393501 ↗

SearchForTestsTask: non-cancellable ReadAction.run() in a background task

Abierto

Encontrado por Background ReadAction Freeze Companion. SearchForTestsTask es un Task.Backgroundable cuyo run() envuelve search() en el cancelable ReadAction.nonBlocking() y, unas líneas después, llama al onFound() hermano con el bloqueante ReadAction.run(), sin ningún checkCanceled() en toda la clase. El Platform Blog de JetBrains señala ese patrón como causa recurrente de congelamientos de la interfaz. Se presentó como IJPL-254654; JetBrains lo movió al proyecto IDEA (Java › Tests) y lo asignó a un desarrollador.

Un comentario de seguimiento (octubre de 2026) agregó dos puntos. La rama de modo smart, la predeterminada, también bloquea: llama al DumbService.runReadActionInSmartMode(), que está deprecado y usa ReadAction.computeBlocking() por dentro. Y cambiar sin más a ReadAction.nonBlocking() no es seguro, porque onFound() escribe archivos y una acción de lectura reiniciada los volvería a escribir. Las dos llamadas siguen en master a octubre de 2026.

IJPL-257836 ↗

DependenciesUsagesPanel.findUsages runs the whole dependency usage search in one non-cancellable read action

Abierto

Encontrado por el mismo control que Background ReadAction Freeze Companion, aplicado como escaneo sobre el propio master de IntelliJ. Al seleccionar un nodo en el Dependency Viewer (Code › Analyze Code › Dependencies), DependenciesUsagesPanel.findUsages() analiza todos los archivos del alcance seleccionado dentro de un único ReadAction.runBlocking() de nivel superior, en un hilo del pool. Una acción de escritura pendiente, como escribir en un editor, espera a que termine toda la búsqueda. El ticket propone la forma de arreglo que JetBrains usó en IJPL-236316 (FindUsagesHelper): una acción de lectura no bloqueante que deje de tragarse ProcessCanceledException, con la actualización de la interfaz fuera de la acción de lectura. El soporte de JetBrains pidió pasos para reproducirlo. Un test sin interfaz sobre un proyecto sintético lo reprodujo: con 2.000 archivos, una acción de escritura esperó 4.8 s a la búsqueda, y 1 ms con una acción de lectura no bloqueante. El test está adjunto al ticket, y el arreglo se propone en el pull request #3684.

IJPL-257854 ↗

Auto-test: the error check of DelayedDocumentWatcher blocks typing until the whole check ends

Abierto

Encontrado con el mismo control, durante una auditoría de componentes que trabajan en segundo plano después de cada edición. Con auto-test activado, DelayedDocumentWatcher espera una pausa de tipeo y luego revisa si cada archivo cambiado tiene errores de sintaxis (PsiErrorElementUtil.hasErrors()) en una sola acción de lectura bloqueante, en un hilo del pool. La tecla que retoma la escritura espera toda la revisión. Medido con el framework de tests de la plataforma sobre IntelliJ IDEA 2025.2: en un archivo de 50.000 líneas, esa tecla tardó 436 ms con el código actual, 48 ms sin auto-test y 73 ms con la revisión en una acción de lectura no bloqueante. El test de medición está adjunto al ticket, y el arreglo se propone en el pull request #3685.

IJPL-257908 ↗

Live Templates settings: isModified() checks every template against every context type on the EDT after each click or key press

Abierto

Encontrado al medir cada página de Settings en el hilo de interfaz de IntelliJ IDEA 2026.2.3 con el framework de tests de la plataforma. El diálogo de Settings llama a isModified() de la página abierta alrededor de un segundo después de cada clic o tecla. En la página Live Templates, esa llamada compara las 1.295 plantillas con los 336 tipos de contexto (TemplateContext.getDifference()), y el hilo de interfaz se detiene unos 165 ms cada vez. El ticket propone una verificación de una línea: dos plantillas con la misma configuración propia de contextos no pueden diferir en ningún tipo de contexto. En el mismo test, esa verificación lleva la comparación de 157 ms a 0 ms con el mismo resultado. El test de medición está adjunto al ticket.

IJPL-257909 ↗

Settings | Plugins: isRequiredForEssentialPlugin rebuilds the plugin maps and walks all essential dependencies once per plugin on the EDT

Abierto

Encontrado en la misma medición de las páginas de Settings. Abrir Settings › Plugins arma la lista de plugins instalados en el hilo de interfaz y pregunta, para cada plugin, si lo requiere un plugin esencial. Cada respuesta vuelve a armar los mapas de plugins y de módulos y recorre las dependencias de todos los plugins esenciales; el propio código ya tiene un FIXME al respecto. Con 158 plugins cargados, la página tardó 689–931 ms en abrir. Un solo recorrido seguido de una búsqueda por plugin tardó 8–22 ms y dio la misma respuesta para cada plugin. El costo crece con el cuadrado de la cantidad de plugins instalados. El test de medición está adjunto al ticket.

IJPL-257919 ↗

Package File: PackageFileWorker does all the file I/O inside one blocking read action, so write actions wait for it

Encontrado por un escaneo del propio master de IntelliJ en busca de trabajo lento dentro de acciones de lectura, y después medido. Build › Package File copia un archivo a los artefactos que lo contienen. PackageFileWorker busca esos artefactos y después hace toda la E/S de archivos dentro del mismo ReadAction.run() bloqueante: la copia, la apertura del archivo comprimido y el reempaquetado de un archivo comprimido anidado. Una acción de escritura pedida mientras tanto, como una tecla, espera a que termine la E/S. Medido con el framework de tests de la plataforma en IntelliJ IDEA 2026.2.3, con un WAR que contiene un JAR de 40 MB: la acción de escritura esperó 2.219–2.508 ms. Con solo la búsqueda de artefactos dentro de la acción de lectura y la E/S fuera, esperó 0 ms en 4 de 4 corridas. El test de medición está adjunto al ticket.

Arreglos aportados

Pull requests enviados al repositorio intellij-community de JetBrains — arreglos para los errores reportados arriba, más inspecciones Java nuevas y extendidas aportadas a la plataforma.

PR #3684 ↗

IJPL-257836 Dependency Viewer: run the usage search in a non-blocking read action

Abierto

Arreglo para IJPL-257836. La búsqueda de usos corre en ReadAction.nonBlocking(...), que se reinicia cuando hay una acción de escritura pendiente, la misma forma de arreglo que JetBrains usó en IJPL-236316. La búsqueda no tiene efectos secundarios, así que reiniciarla es seguro, y la vista de usos se arma después de la acción de lectura. Un test nuevo retiene la búsqueda dentro de su acción de lectura y comprueba que una acción de escritura no la espera. Con los jars de IntelliJ IDEA 2025.2, la acción de escritura esperó 10.021 ms con el código actual y 3 ms con el arreglo. El test no se corrió dentro del build completo de intellij-community.

PR #3685 ↗

IJPL-257854 Auto-test: check changed files for errors in a non-blocking read action

Abierto

Arreglo para IJPL-257854. La revisión de errores corre en ReadAction.nonBlocking(...), que se reinicia cuando hay una acción de escritura pendiente; hasErrors() no tiene efectos secundarios, así que reiniciarla es seguro. Los archivos cambiados se copian antes de la revisión, porque el conjunto se usa en la EDT. Medido con los jars de IntelliJ IDEA 2025.2 y una copia de la clase parcheada: la tecla que retoma la escritura en un archivo de 10.000 líneas tardó 134 ms con el código actual y 25 ms con el arreglo. El cambio no se compiló dentro del build completo de intellij-community.

PR #3694 ↗

IJPL-257908 Live Templates: fast path in TemplateContext.getDifference

Abierto

Arreglo para IJPL-257908. Live Templates recalculaba isModified() en la EDT después de cada clic o tecla (~165 ms en el equipo medido). Un atajo de una línea en TemplateContext.getDifference lo lleva a ~0 ms. La equivalencia se mide en un arnés de reproducción; el test de la inspección lo corre el CI de JetBrains.

PR #3696 ↗

IJPL-257919 Package File: keep the file I/O outside the read action

Abierto

Arreglo para IJPL-257919. Build › Package File ahora resuelve los artefactos de destino dentro de un ReadAction.compute() corto, pero la E/S de archivos (copiar, abrir y reescribir el ZIP, volver a empaquetar un archivo anidado) corre fuera del bloqueo de lectura, así que una acción de escritura ya no la espera. El PackageFileActionTest existente cubre el resultado funcional; la medición de tiempos está adjunta al ticket.

PR #3701 ↗

IJPL-257909 Plugins settings: cache the essential-plugin requirement set

Abierto

Arreglo para IJPL-257909. La página de Settings de Plugins recalculaba, para cada plugin, si lo requiere un plugin esencial (un FIXME en el código). El arreglo guarda ese conjunto en caché por cada instancia de PluginSet y lo invalida estructuralmente cuando se reemplaza el conjunto de plugins. La equivalencia funcional se volvió a confirmar sobre el catálogo de descriptores (158/158).

PR #3697 ↗

IDEA-266545 New Java inspection: magnitude comparison of System.nanoTime()

Abierto

Para IDEA-266545. Una inspección Java nueva (Probable bugs, desactivada por defecto) marca las comparaciones < > <= >= donde un operando es una llamada directa a System.nanoTime(); el modismo correcto de la resta no se marca. La lógica de detección se verificó localmente contra 2026.2.3; el test de la inspección corre en el CI de JetBrains.

PR #3698 ↗

IDEA-279282 Simplifiable Map operations: suggest map.remove(key, value)

Abierto

Para IDEA-279282, una extensión de la inspección existente ‘Simplifiable Map operations’, donde la pidió un mantenedor de JetBrains. Detecta if (value.equals(map.get(key))) map.remove(key) (en ambos órdenes de operandos) y ofrece map.remove(key, value), con resguardos para un valor nulo y para expresiones de clave o valor con efectos secundarios.

PR #3699 ↗

IDEA-279659 New Java inspection: String.compareTo() used for equality

Abierto

Para IDEA-279659. Una inspección Java nueva (Verbose or redundant code, desactivada por defecto) marca compareTo(...) == 0 / != 0 en strings y ofrece equals() / !equals(), restringida a String y con resguardo para la diferencia con un argumento nulo (compareTo(null) lanza una excepción, equals(null) devuelve false). Detección y quick-fix verificados localmente.

Análisis sobre tickets existentes

Comentarios de causa raíz publicados en tickets abiertos de IntelliJ Platform. La mayoría sale de leer el código actual en master; el comentario en IJPL-223452 agrega una reproducción sin interfaz.

IJPL-200871 ↗

CME in workspace model

Corregido

WorkspaceFileIndexDataImpl.fillPackageFilesAndDirectories() recorre un LinkedHashMap sin sincronización que puede cambiar en plena iteración, lo que produce una ConcurrentModificationException. El análisis publicado aquí ubicó esa iteración y propuso una llamada a ProgressManager.checkCanceled(). JetBrains corrigió el ticket el 2026-09-09 con un cambio distinto: las consultas por nombre de paquete ahora llaman a ensureIsUpToDate() antes de leer, de modo que el índice se actualiza primero (commit e1d600df).

IJPL-27359 ↗

CME in InspectionToolRegistrar.createTools on loading/unloading plugins

toolFactories se recorre como una vista viva y sin sincronización de un mapa mutable dentro de createTools(), en hilos de fondo y sin read-action lock, así que una descarga de plugin concurrente puede modificar el mapa en plena iteración. La misma vista viva sigue en master (ahora en Kotlin), así que la falla de 2020 parece reproducible en las mismas condiciones.

IJPL-80817 ↗

Cannot create light service git4ide.repo.GitRepositoryManager because container is already disposed

La llamada original se movió tras una reestructuración del widget, pero la búsqueda del repositorio sigue corriendo bajo el obsoleto runInReadActionWithWriteActionPriority, y ninguna de las funciones auxiliares de la nueva cadena (GitBranchUtil, DvcsUtil, GitUtil) llama a checkCanceled(), así que el cierre de un proyecto todavía puede terminar en una AlreadyDisposedException, con una ventana más estrecha que cuando se reportó.

IJPL-76141 ↗

Git Log is empty due to a StackOverflow exception in IntToIntBtree.processLeafPages

Abierto

processLeafPages se llama recursivamente sin ningún límite de profundidad de pila, así que un índice lo bastante grande desborda la pila y deja el Git Log vacío sin avisar. El mismo método falla en IJPL-250279, reportado de forma independiente cerca de un año después para la caché de compilación de JPS; los dos tickets no estaban vinculados. Corrección propuesta: reescribir el recorrido de forma iterativa.

IJPL-196254 ↗

Memory leak via ProjectRootManagerImpl::rootsChanged

Abierto

La lista changes de BatchSession solo se vacía cuando su contador pendingRootsChanged llega exactamente a 0, pero el contador se incrementa sin el manejo de excepciones correspondiente, así que una excepción o una llamada reentrante asimétrica puede dejarlo trabado por encima de 0 para siempre, y desde ahí changes sigue creciendo con cada evento de cambio de raíces. La falta de esa red de seguridad se ve en el código; el primer desbalance exacto no se rastreó.

IJPL-223452 ↗

PsiSmartPointer improvements

Abierto

Un comentario con una reproducción sin interfaz de la escritura lenta en archivos grandes. Con la ventana Structure armada para un archivo Java de 10.000 métodos, el archivo tiene 10.001 smart pointers, uno por nodo del árbol (PsiTreeAnchorizer). Después de cada tecla, el IDE restaura todos los punteros: en IntelliJ IDEA 2026.2.3, una tecla tardó una mediana de 1.080 ms, contra 33 ms sin la vista de estructura, con el 98% del tiempo en SmartPsiElementPointerImpl.doRestoreElement(). Coincide con los eventos de escritura lenta reportados en IJPL-173280. El test está adjunto al comentario.

Ver también: Casos de estudio