Desarrollo Java

Desarrollo Java para aplicaciones empresariales

Desarrollo backend con Java para nuevas funcionalidades, aplicaciones empresariales y evolución de sistemas existentes.

Pedir diagnóstico gratuito

El reto

Desarrollo y evolución de aplicaciones Java

Una aplicación empresarial puede necesitar nuevas funcionalidades, integraciones o mejoras sin necesidad de sustituir todo el sistema. El objetivo es construir soluciones mantenibles y adaptadas al contexto existente.

Eso implica trabajar dentro de las restricciones que ya hay: la versión de Java en uso, el servidor de aplicaciones, las dependencias que no se pueden tocar todavía y las pruebas que existen o que hay que construir primero.

Qué tipo de trabajo cubre

  • Desarrollo de funcionalidades backend
  • Evolución de aplicaciones Java existentes
  • Mantenimiento y refactorización
  • Integración con sistemas empresariales
  • Desarrollo de servicios backend
  • Análisis de necesidades técnicas

Tecnologías

Con qué se trabaja en el día a día

  • Java
  • Spring
  • Spring Boot
  • Java EE
  • Jakarta EE
  • Hibernate
  • REST
  • SQL
  • Git

Desarrollar dentro de las restricciones que ya hay

En una aplicación empresarial rara vez se elige el punto de partida. Se elige qué hacer con él.

Un desarrollo sobre un sistema en producción viene con condiciones puestas: una versión de Java concreta, un servidor de aplicaciones que no se puede mover todavía, dependencias que nadie quiere tocar y una cobertura de pruebas que es la que es. Ignorar esas condiciones y construir como si el proyecto fuera nuevo produce código que funciona en local y no se puede desplegar.

Trabajar dentro de ellas no significa perpetuarlas. Significa que cada funcionalidad nueva se construye de forma que no añada más deuda, y que las mejoras estructurales se hacen donde hay trabajo de todas formas, no en una tarea aparte que siempre se pospone.

En la práctica eso es lo que hace que una aplicación mejore sin proyectos de modernización: las zonas que se tocan van quedando mejor que como estaban. Cuando el deterioro es demasiado grande para arreglarlo por el camino, entonces sí hace falta un trabajo de modernización con alcance propio.

Los encargos que suelen llegar

  • Una funcionalidad nueva sobre una aplicación que lleva años en producción.
  • Una integración con otro sistema, interno o de un tercero, que hay que construir y mantener.
  • Un módulo concreto que se ha vuelto imposible de cambiar y hay que reconstruir por dentro.
  • Un problema de rendimiento que apareció cuando los datos crecieron.
  • Refuerzo temporal de un equipo que tiene el trabajo identificado pero no las manos.
  • Una segunda opinión técnica sobre una decisión de arquitectura antes de tomarla.

Lo que tienen en común es que hay un sistema existente de por medio. Un desarrollo desde cero, sin restricciones, casi nunca es el caso real.

Cómo se trabaja en la práctica

  1. Entender antes de proponer

    Versión de Java, framework, servidor, cómo se construye, cómo se despliega y qué duele hoy. Una llamada de 30 minutos ahorra semanas de suposiciones, y a veces lo que sale es que no hace falta lo que se venía a pedir.

  2. Acotar el primer entregable

    Algo pequeño, completo y desplegable. Sirve para validar el encaje técnico y la forma de trabajar antes de comprometer nada grande.

  3. Entregar por incrementos que llegan a producción

    Cada entrega pasa por vuestra revisión y sale por el camino de siempre. Sin ramas largas: lo que no se despliega, no se sabe si funciona.

  4. Dejar pruebas con cada cambio

    No como fase final, sino en el mismo commit. En una aplicación sin cobertura, cada funcionalidad nueva es la oportunidad de cubrir el flujo al que pertenece.

  5. Documentar las decisiones, no el código

    Lo que hace falta dentro de un año no es un comentario que repita la línea siguiente, sino saber por qué se descartó la alternativa obvia.

Dónde suelen estar los problemas en un backend Java

Cuatro capas, cada una con sus síntomas propios. Es útil saber cuál es la que está fallando antes de empezar a cambiar cosas.

Capas de un backend Java y qué suele fallar en cada una
CapaSíntoma habitualQué se revisa
PlataformaNo se puede subir una libreríaVersión de Java, servidor de aplicaciones y árbol de dependencias
PersistenciaLa aplicación se degrada según crecen los datosSQL generado, consultas N+1 y límites de las transacciones
IntegraciónUn cambio en un sistema vecino rompe el nuestroContratos explícitos, tolerancia a fallos y reintentos
EntregaDesplegar exige ventana y plan de vuelta atrásCobertura de pruebas, pasos manuales y configuración fuera del repositorio

Los problemas de persistencia que más se repiten

Aparecen cuando los datos crecen, no cuando se escribe el código, y por eso pasan las pruebas y fallan en producción.

LazyInitializationException: could not initialize proxy

Causa: Se accede a una relación perezosa fuera de la transacción que cargó la entidad. Suele salir al serializar la respuesta, con la sesión ya cerrada.

Qué se hace: No alargar la transacción hasta la capa de presentación, sino cargar de forma explícita lo que hace falta, o trabajar con una proyección que solo traiga los campos necesarios.

Una pantalla que lanza 400 consultas para pintar 40 filas

Causa: Consultas N+1: por cada elemento de una lista se lanza una consulta adicional para resolver una relación.

Qué se hace: Traer la relación en la misma consulta cuando de verdad se usa, y activar la traza de SQL en desarrollo. Un JOIN FETCH puntual resuelve la mayoría de los casos sin tocar el mapeo.

OutOfMemoryError al ejecutar un proceso por lotes

Causa: El proceso carga la tabla entera en memoria porque la consulta no pagina y el contexto de persistencia no se vacía nunca.

Qué se hace: Procesar por bloques y limpiar el contexto en cada uno. Un proceso que funciona con mil registros y revienta con un millón no es un problema de memoria disponible.

Bloqueos que solo aparecen con carga real

Causa: Dos flujos actualizan las mismas filas en orden distinto, o una transacción sigue abierta mientras espera a un sistema externo.

Qué se hace: Sacar las llamadas externas fuera de la transacción y unificar el orden de actualización. Reproducirlo exige concurrencia: con un solo usuario no aparece nunca.

Preguntas frecuentes

Dudas frecuentes sobre el desarrollo backend

¿Trabajáis con aplicaciones antiguas o solo con proyectos nuevos?

Sobre todo con aplicaciones que ya están en producción. Un desarrollo sin restricciones previas es la excepción: lo normal es que haya un sistema, un historial y unas condiciones que respetar.

¿Podéis trabajar dentro de nuestro equipo y con nuestro repositorio?

Sí, y es lo habitual. Mismas reglas de revisión y mismo camino a producción que el resto del equipo. Un trabajo que llega en un paquete cerrado al final es imposible de revisar de verdad.

¿Qué pasa si la aplicación no tiene pruebas?

Se construyen sobre el flujo en el que se vaya a trabajar, como parte del encargo y no como extra. Cambiar código sin una red que demuestre que el comportamiento se mantiene es adivinar.

¿Hace falta actualizar la versión de Java para poder desarrollar?

No siempre. Se puede desarrollar sobre la versión actual, y de hecho suele ser lo sensato al principio. Si la versión antigua es lo que bloquea el trabajo, se dice y se aborda como un trabajo aparte con su propio alcance.

¿Hacéis también administración de sistemas o infraestructura?

No. El alcance llega hasta que la aplicación se construye, se prueba y se empaqueta de forma reproducible. Si vuestro proyecto necesita más que eso, os lo digo en la primera llamada.

JavaEvolve

¿Qué necesitáis construir?

Cuéntame qué hay montado y qué falta. Si el encargo no encaja con lo que hago, te lo digo en la primera llamada.

Pedir diagnóstico gratuito

Llamada de 30 minutos, sin coste. Respondo en menos de 48 horas.

En la llamada: versión de Java, framework, servidor y qué duele hoy. Si no puedo ayudarte, te lo digo. Qué incluye el diagnóstico