[opencms-dev] How to package java classes in an opencms module
laurent.druart
laurent.druart at ldict.be
Tue Aug 12 15:05:51 CEST 2025
Hello Michael,
Ok, thank you. I’ll test it.
Kind regards,
Laurent
> Le 12 août 2025 à 14:56, Michael Emmerich via opencms-dev <opencms-dev at opencms.org> a écrit :
>
> Hello Laurent,
>
> the <resources> node in the manifest file tells the system which files or folders should be exported when the module is exported in OpenCms
>
> All exported resources of a module can be found as individual <file> sub-nodes in the <files> node. In those nodes, all resource metadata, like type, date and user created, path, permissions, properties are stored.
>
> Only those resources that are listed in those <file> nodes are imported when you import a module using this manifest file.
>
>
>
> The easiest to do would be:
>
> - Create a new module inside of OpenCms. During Module creation you can select which folders inside the /system/modules/[your-module-name]/ should be created. By default, your module folder is part of the module (and everything inside of it).
>
> - Then upload your .jar and .class files in the corresponding /lib and /classes folder of your module. Make sure that you have set the export points for the /lib and /classes folder in the module configuration
>
> - Export the module from OpenCms and download it. Not extract it and take a look at he manifest file to see what is in there.
>
> The format of those <file> nodes is the same that is used in the manifest files of a database export in OpenCms.
>
>
>
> Kind regards,
>
> Michael
>
>
>
> Am 08.08.25 um 15:27 schrieb laurent.druart via opencms-dev:
>> Hello Michael,
>>
>> Thank you for your answer.
>>
>> The goal of java classes in a module is automatic creation of my context on OpenCMS startup, that’s why I implemented
>>
>> LibraryInitializer extends A_CmsModuleAction implements I_CmsEventListener
>>
>> In a previous test I had a section « resources » like this
>>
>> <resources>
>> <resource uri="/system/modules/com.opencms.library/"/>
>> </resources>
>>
>> but not working at all.
>>
>> So I’ve to create a file section per class in my module? Documentation is not clear on manifest.xml. Do you have an exemple with java classes and lib dependencies?
>>
>> Thanks a lot.
>>
>> Kind regards,
>>
>> Laurent
>>
>>> Le 8 août 2025 à 14:30, Michael Emmerich via opencms-dev <opencms-dev at opencms.org> <mailto:opencms-dev at opencms.org> a écrit :
>>>
>>> Laurent,
>>>
>>> from you manifest, I see that you have not assigned any resources to your module. So no resources are imported when you import the module, therefore the .jar and .classes are missing. I see that you have defined the export points, but without the imported file, this will not work.
>>>
>>> However, we usually do not put .jar or .class files in our modules, we deploy them separately on the server as yo have to restart it anyway after deploying some .jar and .class files.
>>>
>>>
>>> Kind regards,
>>>
>>> Michael
>>>
>>>
>>>
>>> Am 08.08.25 um 11:22 schrieb laurent.druart via opencms-dev:
>>>> Hello,
>>>>
>>>> In add-on to my previous e-mail, here is the content/structure of my zip files :
>>>>
>>>>
>>>> And the content of my manifest.xml :
>>>>
>>>> <?xml version="1.0" encoding="UTF-8"?>
>>>> <export>
>>>> <info>
>>>> <creator>OpenCMS Module Builder</creator>
>>>> <opencms_version>19.0</opencms_version>
>>>> <createdate>Wed, 07 Aug 2025 10:00:00 GMT</createdate>
>>>> <project>Offline</project>
>>>> <export_version>7</export_version>
>>>> </info>
>>>>
>>>> <module>
>>>> <name>com.opencms.library</name>
>>>> <nicename>OpenCMS Spring Data JDBC Library</nicename>
>>>> <group>Custom Libraries</group>
>>>> <class>com.opencms.library.integration.LibraryInitializer</class>
>>>> <description>Librairie Spring classique pour OpenCMS avec accès aux données PostgreSQL</description>
>>>> <version>1.0.0</version>
>>>> <authorname>Laurent Druart</authorname>
>>>> <authoremail>laurent.druart at ldict.be <mailto:laurent.druart at ldict.be></authoremail>
>>>> <datecreated>Wed, 07 Aug 2025 10:00:00 GMT</datecreated>
>>>> <userinstalled>Admin</userinstalled>
>>>> <dateinstalled>Wed, 07 Aug 2025 10:00:00 GMT</dateinstalled>
>>>>
>>>> <dependencies/>
>>>>
>>>> <exportpoints>
>>>> <exportpoint uri="/system/modules/com.opencms.library/classes/" destination="WEB-INF/classes/"/>
>>>> <exportpoint uri="/system/modules/com.opencms.library/lib/" destination="WEB-INF/lib/"/>
>>>> </exportpoints>
>>>> <resources/>
>>>> <parameters>
>>>> <param name="spring.auto.init">true</param>
>>>> </parameters>
>>>> </module>
>>>>
>>>> <files/>
>>>> </export>
>>>>
>>>> I tried to import the zip in the modules app, module is created but classes and lib are not copied in WEB-INF folders and in the explorer app there are no « com.opencms.library » entries in /system/modules
>>>>
>>>> Thanks for your help.
>>>>
>>>> Regards,
>>>>
>>>> Laurent
>>>>
>>>>> Le 7 août 2025 à 16:41, laurent.druart via opencms-dev <opencms-dev at opencms.org> <mailto:opencms-dev at opencms.org> a écrit :
>>>>>
>>>>> 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
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> This mail is sent to you from the opencms-dev mailing list
>>>>> To change your list options, or to unsubscribe from the list, please visit
>>>>> https://lists.opencms.org/mailman/listinfo/opencms-dev
>>>>>
>>>>>
>>>>>
>>>>
>>>> _______________________________________________
>>>> This mail is sent to you from the opencms-dev mailing list
>>>> To change your list options, or to unsubscribe from the list, please visit
>>>> https://lists.opencms.org/mailman/listinfo/opencms-dev
>>>>
>>>>
>>>>
>>> --
>>> Michael Emmerich
>>> Alkacon Software GmbH & Co. KG - The OpenCms Experts
>>> http://www.alkacon.com <http://www.alkacon.com/>
>>> http://www.opencms.org <http://www.opencms.org/>
>>>
>>> _______________________________________________
>>> This mail is sent to you from the opencms-dev mailing list
>>> To change your list options, or to unsubscribe from the list, please visit
>>> https://lists.opencms.org/mailman/listinfo/opencms-dev
>>>
>>>
>>>
>>
>>
>>
>> _______________________________________________
>> This mail is sent to you from the opencms-dev mailing list
>> To change your list options, or to unsubscribe from the list, please visit
>> https://lists.opencms.org/mailman/listinfo/opencms-dev
>>
>>
>>
> --
> Michael Emmerich
>
> -------------------
>
> Alkacon Software GmbH & Co. KG - The OpenCms Experts
> Michael Emmerich
> An der Wachsfabrik 13
> 50996 Koeln, DE
>
> Tel: +49 (0)2236 3826-14
> Fax: +49 (0)2236 3826-20
> Email: m.emmerich at alkacon.com <mailto:m.emmerich at alkacon.com>
>
> http://www.alkacon.com <http://www.alkacon.com/>
> http://www.opencms.org <http://www.opencms.org/>
>
> Amtsgericht Köln, HRA 32185, USt-IdNr.: DE259882372
> Vertreten durch: Alkacon Verwaltungs GmbH
> Geschäftsführer: Alexander Kandzior, Amtsgericht Köln, HRB 88218
> _______________________________________________
> This mail is sent to you from the opencms-dev mailing list
> To change your list options, or to unsubscribe from the list, please visit
> https://lists.opencms.org/mailman/listinfo/opencms-dev
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.opencms.org/pipermail/opencms-dev/attachments/20250812/e30edd77/attachment.htm>
More information about the opencms-dev
mailing list