Los repositorios institucionales suelen ser sistemas muy estables. Sin embargo, cuando aparecen errores poco frecuentes, especialmente durante migraciones o reconstrucciones de plataformas, resolverlos requiere algo más que conocer DSpace: exige comprender cómo interactúan la base de datos, el índice OAI, el sistema de permisos y el propio código fuente.
Recientemente, durante un proyecto de recuperación de un repositorio institucional basado en DSpace 6, nos encontramos con uno de esos casos.
Al reconstruir completamente el índice OAI-PMH mediante el comando:
[dspace]/bin/dspace oai import -c -v
el proceso comenzaba normalmente, indexando cientos de registros, hasta detenerse siempre en el mismo punto con el siguiente error:
java.lang.NullPointerException
at org.dspace.xoai.app.XOAI.willChangeStatus(...)
Lo curioso era que el mismo repositorio funcionaba correctamente para los usuarios, las búsquedas Discovery respondían sin problemas y la interfaz web no presentaba errores.
El fallo aparecía únicamente al reconstruir el índice OAI.
Como el proceso siempre se detenía aparentemente sobre el mismo registro, la primera sospecha fue un ítem dañado.
Comenzamos revisando:
withdrawn, in_archive)Incluso eliminamos temporalmente algunos registros para verificar la hipótesis.
Sin embargo, el error persistía exactamente igual.
Durante la investigación encontramos otro problema independiente.
Al exportar determinadas colecciones aparecía:
FileNotFoundException
porque algunos bitstreams apuntaban a archivos físicos inexistentes dentro del assetstore.
Era un problema real, pero no explicaba el NullPointerException.
Corregimos los archivos faltantes y el error OAI continuó exactamente igual.
La traza siempre apuntaba al método:
willChangeStatus()
de XOAI.
Esto nos llevó a inspeccionar directamente el comportamiento interno del componente OAI de DSpace.
Durante esa revisión descubrimos que el método analiza los permisos READ asociados a cada objeto antes de decidir si un registro debe publicarse o eliminarse del índice.
Fue entonces cuando apareció una pista importante.
Al revisar la tabla resourcepolicy encontramos aproximadamente 200 políticas READ asignadas directamente a usuarios individuales (EPerson).
Es decir, permisos definidos mediante:
eperson_id
en lugar de pertenecer a un grupo (epersongroup).
Estas políticas provenían de operaciones realizadas años atrás y coexistían normalmente con el resto del repositorio.
El problema era que XOAI asumía que toda política READ tenía asociado un grupo.
En determinadas condiciones terminaba ejecutando una llamada equivalente a:
policy.getGroup().getName()
sin comprobar previamente si el grupo existía.
Cuando la política pertenecía únicamente a un usuario individual, getGroup() devolvía null, produciendo el famoso:
NullPointerException
Antes de cualquier modificación realizamos un respaldo completo de las políticas afectadas.
Posteriormente eliminamos únicamente las políticas READ asignadas a usuarios individuales:
DELETE FROM resourcepolicy
WHERE action_id = 0
AND eperson_id IS NOT NULL
AND epersongroup_id IS NULL;
Tras reconstruir nuevamente el índice OAI:
dspace oai import -c
la indexación finalizó correctamente.
El error desapareció por completo.
Depende del contexto.
En nuestro caso se trataba de un repositorio público donde el acceso estaba definido principalmente mediante:
Las políticas individuales eran residuales y no formaban parte del modelo de autorización esperado.
Por ello su eliminación no modificó el comportamiento del repositorio.
No obstante, antes de realizar cualquier cambio siempre recomendamos:
resourcepolicy;Este caso dejó varias enseñanzas interesantes.
Encontramos archivos inexistentes, bitstreams sin respaldo y otros problemas durante el análisis.
Todos ellos eran errores legítimos, pero ninguno provocaba el fallo de XOAI.
Es importante no confundir problemas encontrados durante el camino con la causa raíz del incidente.
Cada hipótesis fue validada mediante evidencia:
Esa metodología permitió llegar finalmente al origen del problema.
DSpace no es solamente una aplicación web.
Su funcionamiento depende de múltiples componentes:
Un síntoma puede originarse en cualquiera de ellos.
Muchos repositorios institucionales llevan más de diez años en producción.
Durante ese tiempo atraviesan migraciones, actualizaciones, cambios de políticas, desarrollos propios y modificaciones manuales.
Es común encontrar configuraciones perfectamente válidas para una versión antigua que terminan generando comportamientos inesperados en componentes más recientes.
Resolver problemas complejos no consiste únicamente en conocer comandos o memorizar soluciones.
Consiste en formular hipótesis, validarlas con evidencia y avanzar paso a paso hasta comprender realmente qué está ocurriendo.
En infraestructura digital, la paciencia suele ser tan importante como el conocimiento técnico.
Y quizás esa sea la principal enseñanza de este caso: antes de cambiar configuraciones al azar, conviene entender cómo funciona el sistema. Cuando se comprende la arquitectura, las soluciones dejan de ser improvisaciones y se convierten en decisiones fundamentadas.