Problème binding entre module avec Guice

Bonjour,

Je me permet de poster un soucis que j’ai depuis maintenant plusieurs jours avec les modules d’Axelor…
En effet, lors de l’ajout du “Module2”, ce dernier ne se lance pas sur une instance de tomcat, j’ai une erreur après la phase de scan des jar (scanning JPA…)
pour info :
Mon application se compile sans erreurs (./gradlew clean build -x test).
L’application se lance sans aucun soucis sur une instance tomcat quand j’enlève le module 2.

Le but est que le module 2 soit dépendant du module 1. L’idée est de gérer mon application via différentes “couches” que je veux ordonner via des modules.
Mais j’ai un soucis de binding avec Google Guice sur mon module 2 par rapport au module 1… je ne comprends pas, l’erreur semble venir du module “axelor-base”, mais je n’ai rien touché aux sources d’axelor…

OS : Ubuntu 18.04
Ide : IntelliJ 2018.3.3
Axelor development kit : 4.1.7
Abs-webapp : 4.0.0

Dans l’attente d’une réponse,

Cdt,

public class Module1 extends AxelorModule {

@Override
protected void configure() {
    bind(AccountManagementServiceAccountImpl.class).to(AccountManagementServiceModule1.class);
    bind(AccountCustomerService.class).to(AccountCustomerServiceModule1.class);
    bind(MoveLineService.class).to(MoveLineServiceModule1.class);
    bind(MoveLineExportService.class).to(MoveLineExportServiceModule1.class);
    bind(MoveLineReportServiceImpl.class).to(MoveLineReportServiceModule1.class);

bind(AddressServiceAccountImpl.class).to(AddressServiceModule1.class);
bind(AddressBaseRepository.class).to(AddressRepositoryModule1.class);
bind(CityRepository.class).to(CityRepositoryModule1.class);
bind(PartnerAddressRepository.class).to(PartnerAddressRepositoryModule1.class);
bind(PartnerSaleService.class).to(PartnerServiceModule1.class);
bind(PartnerAccountRepository.class).to(PartnerRepositoryModule1.class);

bind(SaleOrderSupplychainRepository.class).to(SaleOrderRepositoryModule1.class);
bind(SaleOrderServiceProductionImpl.class).to(SaleOrderServiceModule1.class);
bind(SaleOrderStockServiceImpl.class).to(SaleOrderStockServiceModule1.class);
bind(SaleOrderInvoiceProjectServiceImpl.class).to(SaleOrderInvoiceServiceModule1.class);
bind(SaleOrderPurchaseServiceImpl.class).to(SaleOrderPurchaseServiceModule1.class);

bind(SaleOrderLineServiceSupplyChainImpl.class).to(SaleOrderLineServiceModule1.class);
bind(SaleOrderLineRepository.class).to(SaleOrderLineRepositoryModule1.class);

bind(PurchaseOrderSupplychainRepository.class).to(PurchaseOrderRepositoryModule1.class);
bind(PurchaseOrderServiceSupplychainImpl.class).to(PurchaseOrderServiceModule1.class);
bind(PurchaseOrderLineServiceImpl.class).to(PurchaseOrderLineServiceModule1.class);
bind(PurchaseOrderInvoiceProjectServiceImpl.class).to(PurchaseOrderInvoiceServiceModule1.class);
bind(PurchaseOrderLineRepository.class).to(PurchaseOrderLineRepositoryModule1.class);

bind(PriceListService.class).to(PriceListServiceModule1.class);

bind(LocationServiceImpl.class).to(LocationServiceModule1.class);
bind(LocationLineServiceImpl.class).to(LocationLineServiceModule1.class);

bind(StockMoveServiceSupplychainImpl.class).to(StockMoveServiceModule1.class);
bind(StockMoveLineSupplychainServiceImpl.class).to(StockMoveLineServiceModule1.class);
bind(StockMoveLineRepository.class).to(StockMoveLineRepositoryModule1.class);
bind(StockMoveManagementRepository.class).to(StockMoveRepositoryModule1.class);
bind(StockMoveInvoiceServiceImpl.class).to(StockMoveInvoiceServiceModule1.class);
bind(ManufOrderStockMoveService.class).to(ManufOrderStockMoveServiceModule1.class);

bind(InventoryService.class).to(InventoryServiceModule1.class);

bind(InvoiceManagementRepository.class).to(InvoiceRepositoryModule1.class);
bind(InvoiceServiceImpl.class).to(InvoiceServiceModule1.class);

bind(BillOfMaterialServiceImpl.class).to(BillOfMaterialServiceModule1.class);
bind(BillOfMaterialManagementRepository.class).to(BillOfMaterialRepositoryModule1.class);
bind(OperationOrderWorkflowService.class).to(OperationOrderWorkFlowServiceModule1.class);
bind(ManufOrderServiceBusinessImpl.class).to(ManufOrderServiceModule1.class);
bind(ManufOrderManagementRepository.class).to(ManufOrderRepositoryModule1.class);
bind(ManufOrderWorkflowService.class).to(ManufOrderWorkFlowServiceModule1.class);

bind(TemplateMessageServiceBaseImpl.class).to(TemplateMessageServiceModule1.class);

bind(DurationServiceImpl.class).to(DurationServiceModule1.class);
bind(MrpServiceProductionImpl.class).to(MrpServiceModule1.class);
bind(MrpLineServiceProductionImpl.class).to(MrpLineServiceModule1.class);

bind(SaleOrderLineTaxService.class).to(SaleOrderLineTaxServiceModule1.class);

bind(VentilateStateSupplyChain.class).to(VentilateStateModule1.class);
bind(ValidateState.class).to(ValidateStateModule1.class);
bind(ValidateFactory.class).to(ValidateFactoryModule1.class);

bind(GenerateMessageController.class).to(GenerateMessageControllerModule1.class);
}
}

build.gradle module 1 :

apply plugin: 'axelor-module'

module {
	name "module1"
	title "Module1"
version "4.1.0"

	// module dependencies
module "modules:axelor-exception"
module "modules:axelor-tool"
module "modules:axelor-message"
module "modules:axelor-base"
module "modules:axelor-crm"
module "modules:axelor-account"
module "modules:axelor-supplychain"
module "modules:axelor-production"
module "modules:axelor-purchase"
module "modules:axelor-sale"
module "modules:axelor-stock"
module "modules:axelor-supplier-management"
module "modules:axelor-human-resource"
module "modules:axelor-business-project"
module "modules:axelor-project"
module "modules:axelor-business-production"

build.gradle module 2 :

 apply plugin: 'axelor-module'

module {
	name "Module2"
	title "Module2"

	version "4.1.0"

	module "modules:module1"
	
}

public class Module2 extends AxelorModule {

@Override
protected void configure() {
    bind( ProductServiceModule1.class).to( ProductServiceModule2.class);
    bind( BillOfMaterialServiceModule1.class).to( BillOfMaterialServiceModule2.class);
    bind( ManufOrderWorkFlowServiceModule1.class).to( ManufOrderWorkFlowServiceModule2.class);
    bind( OperationOrderWorkFlowServiceModule1.class).to( OperationOrderWorkFlowServiceModule2.class);
    bind( PalletServiceModule1.class).to( PalletServiceModule2.class);
    bind( ManufOrderStockMoveServiceModule1.class).to( ManufOrderStockMoveServiceModule2.class);
    bind( ManufOrderServiceModule1.class).to( ManufOrderServiceModule2.class);
    bind( StockMoveProductionServiceModule1.class).to( StockMoveProductionServiceModule2.class);
    bind( StockMoveServiceModule1.class).to( StockMoveServiceModule2.class);
    bind( StockMoveController.class).to( StockMoveControllerModule2class);
    bind( StockMoveLineServiceModule1.class).to( StockMoveLineServiceModule2.class);
    bind( PurchaseOrderLineServiceModule1.class).to( PurchaseOrderLineServiceModule2.class);
    bind( PurchaseOrderServiceModule1.class).to( PurchaseOrderServiceModule2.class);
}

}

Logs tomcat Localhost :
28-Jan-2019 09:08:03.006 GRAVE [localhost-startStop-1] org.apache.catalina.core.StandardContext.listenerStart Exception lors de l’envoi de l’évènement contexte initialisé (context initialized) à l’instance de classe d’écoute (listener) com.axelor.web.AppContextListener
com.google.inject.CreationException: Unable to create injector, see the following errors:

  1. No implementation for com.axelor.apps.base.service.administration.GeneralService was bound.
    while locating com.axelor.apps.base.service.administration.GeneralService
    for field at com.axelor.apps.base.service.MapService.generalService(MapService.java:51)
    while locating com.axelor.apps.base.service.MapService
    for field at com.axelor.web.MapRest.mapService(MapRest.java:48)
    at com.axelor.web.AppServletModule.configureServlets(AppServletModule.java:155)

  2. An exception was caught and reported. Message: null
    at com.axelor.web.AppServletModule.configureServlets(AppServletModule.java:121) (via modules: com.axelor.web.AppServletModule -> com.axelor.app.AppModule)

2 errors
at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:466)
at com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:155)
at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:107)
at com.google.inject.Guice.createInjector(Guice.java:96)
at com.google.inject.Guice.createInjector(Guice.java:73)
at com.google.inject.Guice.createInjector(Guice.java:62)
at com.axelor.web.AppContextListener.getInjector(AppContextListener.java:82)
at com.google.inject.servlet.GuiceServletContextListener.contextInitialized(GuiceServletContextListener.java:47)
at com.axelor.web.AppContextListener.contextInitialized(AppContextListener.java:44)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4727)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5189)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:752)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:728)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734)
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:952)
at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1823)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException
at com.axelor.app.AppModule.configure(AppModule.java:79)
at com.google.inject.AbstractModule.configure(AbstractModule.java:62)
at com.google.inject.spi.Elements$RecordingBinder.install(Elements.java:340)
at com.google.inject.AbstractModule.install(AbstractModule.java:122)
at com.axelor.web.AppServletModule.configureServlets(AppServletModule.java:121)
at com.google.inject.servlet.ServletModule.configure(ServletModule.java:55)
at com.google.inject.AbstractModule.configure(AbstractModule.java:62)
at com.google.inject.spi.Elements$RecordingBinder.install(Elements.java:340)
at com.google.inject.spi.Elements.getElements(Elements.java:110)
at com.google.inject.internal.InjectorShell$Builder.build(InjectorShell.java:138)
at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:104)
… 19 more

pouvez-vous fournir le code du module2, celui que vous avez-mis est le module1 ? est-ce le même ?

Bonsoir @femtonext !
Merci de ta réponse rapide,

Le code du module 2 est bien présent dans le même “pavé” que celui du module 1.

Je vais essayé d’améliorer la présentation, mais tout est présent pour le moment

Bien cordialement,

désolé, sur mobile pas toujours simple de lire des pavés de code.
J’aimerai comprendre le rôle des modules 1 & 2. Dans le module 2 tu fais un bind de la même classe du module 1 ??? je ne vois pas exactement le but recherché !

Bonjour @femtonext,

Le but est de gérer Axelor par “couches”. Le module1 est une couche généraliste, qui reprends les standards d’Axelor.
Quant à lui, le module2 est une couche spécifique métier.
Si plus tard, les besoins métiers évoluent, il sera plus facile de supprimer le module2 lié au métier, et de refaire un module. Mais le module1 sera lui toujours présent, c’est une sorte de “base” supplémentaire au noyau d’Axelor.

2-------Couche Spécifique Métier module2
1-------Couche Général module1
0-------Couche Noyau Axelor

Cdt,

Bonjour,
Merci pour ces précisions. Me confirmez-vous que votre classe com.axelor.apps.base.service.administration.GeneralService dispose bien d’un constructeur public sans argument ? ou s’il dispose d’un argument celui-ci est-il bien annoté ?

Bonjour @femtonext,

Ma classe GeneralService dispose bien d’un constructeur public sans argument, et donc sans annotation.

C’est exactement la même que sur l’abs 4.0.0 :
https://github.com/axelor/axelor-business-suite/blob/v4.0.0/axelor-base/src/main/java/com/axelor/apps/base/service/administration/GeneralService.java

vous utilisez donc une veille version…le problème rencontré est lié à un probleme de résolution de dépendance. Guice n’arrive pas à créer une instance du bind…désolé mais là ce me dépasse, je ne suis pas un spécialiste de Guice. Désolé.

Bon, je vais attendre si quelqu’un passant par là aurait une idée… Sinon j’irais essayer sur le forum de guice…

@femtonext En tout cas, merci d’avoir pris le temps de me répondre !

Cdt,

Problème résolu, vraisemblablement, ce n’était pas un soucis lié à Guice, mais plutôt à IntelliJ qui détectait mal mon module 2.
Procédure utilisé :
Suppression et recréation du module 2
Aucuns changements effectués sur les fichiers.
Compilation + lancement sur une instance de Tomcat : ok

Cdt,

bon à savoir, merci. vous pouvez marquer votre topic comme résolu :slight_smile:

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.