[opencms-dev] How to package java classes in an opencms module

laurent.druart laurent.druart at ldict.be
Thu Aug 7 16:41:25 CEST 2025


Hello,

I’m still testing OpenCMS and i wrote a very small library, a spring based library. I want to use the beans in my jsp so i wrote 2 classes:

SpringBeanUtils :

public class SpringBeanUtils {

    private static final Log LOG = CmsLog.getLog(SpringBeanUtils.class);

    /**
     * Récupère le service utilisateur
     * Exemple d'utilisation dans une page JSP :
     * <%
     *   UserService userService = SpringBeanUtils.getUserService();
     *   List<User> users = userService.getAllActiveUsers();
     * %>
     */
    public static UserService getUserService() {
        try {
            return LibraryInitializer.getBean(UserService.class);
        } catch (Exception e) {
            LOG.error("Erreur lors de la récupération du UserService", e);
            throw new RuntimeException("Service utilisateur non disponible", e);
        }
    }

    /**
     * Méthode générique pour récupérer n'importe quel service
     * Exemple :
     * MyService service = SpringBeanUtils.getService(MyService.class);
     */
    public static <T> T getService(Class<T> serviceClass) {
        try {
            return LibraryInitializer.getBean(serviceClass);
        } catch (Exception e) {
            LOG.error("Erreur lors de la récupération du service: " + serviceClass.getSimpleName(), e);
            throw new RuntimeException("Service non disponible: " + serviceClass.getSimpleName(), e);
        }
    }

    /**
     * Récupère un bean par son nom
     * Exemple :
     * Object bean = SpringBeanUtils.getBean("userService");
     */
    public static Object getBean(String beanName) {
        try {
            return LibraryInitializer.getBean(beanName);
        } catch (Exception e) {
            LOG.error("Erreur lors de la récupération du bean: " + beanName, e);
            throw new RuntimeException("Bean non disponible: " + beanName, e);
        }
    }

    /**
     * Vérifie si le contexte Spring est disponible
     */
    public static boolean isAvailable() {
        return LibraryInitializer.isSpringContextAvailable();
    }

    /**
     * Méthode utilitaire pour vérifier la disponibilité avant utilisation
     */
    public static void ensureAvailable() {
        if (!isAvailable()) {
            throw new IllegalStateException(
                    "Le contexte Spring n'est pas disponible. " +
                            "Vérifiez que le module est correctement initialisé."
            );
        }
    }
}

with static method getUserService() I can call the userService bean. No problem with it.

And second class LibraryInitializer wich must initialise the spring context and configure it:

public class LibraryInitializer extends A_CmsModuleAction implements I_CmsEventListener {

    private static final String MODULE_NAME = "opencms-spring-library";
    private static ApplicationContext springContext;
    private static final org.apache.commons.logging.Log LOG = CmsLog.getLog(LibraryInitializer.class);

    /**
     * Initialisation du module
     */
    @Override
    public void initialize(org.opencms.file.CmsObject adminCms,
                           org.opencms.configuration.CmsConfigurationManager configurationManager,
                           CmsModule module) {

        LOG.info("Initialisation de la librairie Spring classique pour OpenCMS");

        try {
            // Configuration des propriétés système
            configureSystemProperties();

            // Création du contexte Spring CLASSIQUE
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
            context.register(com.opencms.library.config.LibraryConfiguration.class);
            context.refresh();

            springContext = context;

            // Enregistrement des listeners OpenCMS
            OpenCms.addCmsEventListener(this);

            LOG.info("Librairie Spring classique initialisée avec succès");

        } catch (Exception e) {
            LOG.error("Erreur lors de l'initialisation de la librairie Spring", e);
            throw new RuntimeException("Impossible d'initialiser la librairie Spring", e);
        }
    }

    /**
     * Arrêt du module
     */
    @Override
    public void shutDown(CmsModule module) {
        LOG.info("Arrêt de la librairie Spring classique");

        if (springContext != null) {
            try {
                if (springContext instanceof AnnotationConfigApplicationContext) {
                    ((AnnotationConfigApplicationContext) springContext).close();
                }
                LOG.info("Contexte Spring fermé avec succès");
            } catch (Exception e) {
                LOG.error("Erreur lors de l'arrêt du contexte Spring", e);
            } finally {
                springContext = null;
            }
        }
    }

    /**
     * Gestion des événements OpenCMS
     */
    @Override
    public void cmsEvent(CmsEvent event) {
        switch (event.getType()) {
            case I_CmsEventListener.EVENT_PUBLISH_PROJECT:
                LOG.debug("Événement de publication détecté");
                break;
            case I_CmsEventListener.EVENT_CLEAR_CACHES:
                LOG.debug("Événement de nettoyage des caches détecté");
                break;
        }
    }

    /**
     * Configuration des propriétés système
     */
    private void configureSystemProperties() {
        // Configuration de base de données (valeurs par défaut)
        if (System.getProperty("spring.datasource.url") == null) {
            System.setProperty("spring.datasource.url", "jdbc:postgresql://postgres-db:5432/libdb");
        }
        if (System.getProperty("spring.datasource.username") == null) {
            System.setProperty("spring.datasource.username", "appuser");
        }
        if (System.getProperty("spring.datasource.password") == null) {
            System.setProperty("spring.datasource.password", "apppassword");
        }

        LOG.info("Propriétés système configurées");
    }

    /**
     * Accès aux beans Spring
     */
    public static <T> T getBean(Class<T> beanClass) {
        if (springContext == null) {
            throw new IllegalStateException("Le contexte Spring n'est pas initialisé");
        }
        return springContext.getBean(beanClass);
    }

    public static Object getBean(String beanName) {
        if (springContext == null) {
            throw new IllegalStateException("Le contexte Spring n'est pas initialisé");
        }
        return springContext.getBean(beanName);
    }

    public static boolean isSpringContextAvailable() {
        return springContext != null;
    }
}

If i build this lib as a jar and put it in WEB-INF/lib i can access my beans in jsp pages but i must do this call first:

           com.opencms.library.integration.LibraryInitializer initializer =
                new com.opencms.library.integration.LibraryInitializer();

            // Appel direct de initialize avec des paramètres nulls (notre version simplifiée les gère)
            initializer.initialize(null, null, null);
after that my context is initialized and configured and my jsp are running fine. But the way to automatic loading of my context seems to be an opencms module.

I tried to adapt my lib with opencms-module.xml, manifest.xml,... but nothing works: at startup com.opencms.library.integration.LibraryInitializer is not found by opencms.

Can you help me?
Does it exist a tutorial or how-to?

Am i wrong with public class LibraryInitializer extends A_CmsModuleAction implements I_CmsEventListener ?

Thank you

Kind regards,

Laurent




More information about the opencms-dev mailing list