Composite Projects - user addon

In my project the user is being used in almost all other addons. In composite projects the user entity and security is created in application subproject only. As the main application has dependencies from other projects, i can’t use user from main app in other addons due to circular dependencies.

T o solve this, I want to make a separate user addon to handle security and this can have dependencies with other subprojects.

How can I do this in studio.

You should create an add-on and move the User entity and related stuff from the application to this add-on.

Take a look at this composite project:

It includes the users add-on with the dedicated User entity, so you can use it as an example.

Hi Konstantin
I have the same question, how we can use the same user in different add-ons. Comments/questions:

  1. I see you have created user addon. Is it just a simple add-on where you have created the user Entity and screens as usual like any other Entities created (e.g. customer, product etc.) ? How will this working with the security?
  2. I couldn’t test it as it was not loaded, got the following exception, basically the similar issue i faced and reported in the forum here:
    image

Move user entity from main project to user addon and update security files for same (I have updated the table name also). Add security dependencies to all addons where user will be used. It worked for me.

Can you indicate where and what exactly I change in the security files? Any code snippets you want to share?

Move security folder also and do change as user entity has moved from one main app to addon, so its reference will change in import. I just run the app and wherever it says user entity not found change the import setting in file.

Hi Konstantin
I downloaded the sample application and tried to run but getting the following errors:

/Users/mak/Library/Java/JavaVirtualMachines/openjdk-17.0.1/Contents/Home/bin/java liquibase.integration.commandline.Main --driver org.hsqldb.jdbc.JDBCDriver --changeLogFile liquibase-change-log-1655936496111.xml --url jdbc:hsqldb:file:/Users/mak/Projects/samples/sample-composite-project-main/all/.jmix/hsqldb/sales;shutdown=true --username sa --logLevel INFO update
[2022-06-22 18:21:36] INFO [liquibase.integration] No Liquibase Pro license key supplied. Please set liquibaseProLicenseKey on command line or in liquibase.properties to use Liquibase Pro features.
Liquibase Community 4.5.0 by Datical
####################################################
##   _     _             _ _                      ##
##  | |   (_)           (_) |                     ##
##  | |    _  __ _ _   _ _| |__   __ _ ___  ___   ##
##  | |   | |/ _` | | | | | '_ \ / _` / __|/ _ \  ##
##  | |___| | (_| | |_| | | |_) | (_| \__ \  __/  ##
##  \_____/_|\__, |\__,_|_|_.__/ \__,_|___/\___|  ##
##              | |                               ##
##              |_|                               ##
##                                                ## 
##  Get documentation at docs.liquibase.com       ##
##  Get certified courses at learn.liquibase.com  ## 
##  Free schema change activity reports at        ##
##      https://hub.liquibase.com                 ##
##                                                ##
####################################################
Starting Liquibase at 18:21:36 (version 4.5.0 #52 built at 2021-09-27 16:19+0000)
[2022-06-22 18:21:36] INFO [liquibase.database] Set default schema name to PUBLIC
[2022-06-22 18:21:36] INFO [liquibase.lockservice] Successfully acquired change log lock
[2022-06-22 18:21:37] INFO [liquibase.changelog] Reading resource: com/company/sales/liquibase/changelog/2021/12/03-010-152c3480.xml
[2022-06-22 18:21:37] INFO [liquibase.changelog] Reading resource: com/company/sales/liquibase/changelog/2021/12/03-020-152c3480.xml
[2022-06-22 18:21:37] INFO [liquibase.changelog] Reading resource: com/company/sales/liquibase/changelog/2021/12/03-030-152c3480.xml
[2022-06-22 18:21:37] INFO [liquibase.changelog] Reading from PUBLIC.DATABASECHANGELOG
[2022-06-22 18:21:37] INFO [liquibase.lockservice] Successfully released change log lock
[2022-06-22 18:21:37] INFO [liquibase.lockservice] Successfully acquired change log lock
Skipping auto-registration
[2022-06-22 18:21:37] WARNING [liquibase.hub] Skipping auto-registration
[2022-06-22 18:21:37] INFO [liquibase.lockservice] Successfully released change log lock
18:21:37.685 [main] INFO hsqldb.db.HSQLDB818D80F174.ENGINE - Database closed
Unexpected error running Liquibase: Migration failed for change set com/company/products/liquibase/changelog/001-products-addon.xml::2::products-addon:
     Reason: liquibase.exception.DatabaseException: user lacks privilege or object not found: PUBLIC.USR_USER [Failed SQL: (-5501) ALTER TABLE PUBLIC.PRD_PRODUCT ADD CONSTRAINT FK_PRD_PRODUCT_ON_MAINTAINER FOREIGN KEY (MAINTAINER_ID) REFERENCES PUBLIC.USR_USER (ID)]
For more information, please use the --logLevel flag
[2022-06-22 18:21:37] SEVERE [liquibase.integration] Unexpected error running Liquibase: Migration failed for change set com/company/products/liquibase/changelog/001-products-addon.xml::2::products-addon:
     Reason: liquibase.exception.DatabaseException: user lacks privilege or object not found: PUBLIC.USR_USER [Failed SQL: (-5501) ALTER TABLE PUBLIC.PRD_PRODUCT ADD CONSTRAINT FK_PRD_PRODUCT_ON_MAINTAINER FOREIGN KEY (MAINTAINER_ID) REFERENCES PUBLIC.USR_USER (ID)]
liquibase.exception.LiquibaseException: liquibase.exception.MigrationFailedException: Migration failed for change set com/company/products/liquibase/changelog/001-products-addon.xml::2::products-addon:
     Reason: liquibase.exception.DatabaseException: user lacks privilege or object not found: PUBLIC.USR_USER [Failed SQL: (-5501) ALTER TABLE PUBLIC.PRD_PRODUCT ADD CONSTRAINT FK_PRD_PRODUCT_ON_MAINTAINER FOREIGN KEY (MAINTAINER_ID) REFERENCES PUBLIC.USR_USER (ID)]
	at liquibase.changelog.ChangeLogIterator.run(ChangeLogIterator.java:124)
	at liquibase.Liquibase.lambda$null$0(Liquibase.java:265)
	at liquibase.Scope.lambda$child$0(Scope.java:177)
	at liquibase.Scope.child(Scope.java:186)
	at liquibase.Scope.child(Scope.java:176)
	at liquibase.Scope.child(Scope.java:155)
	at liquibase.Scope.child(Scope.java:239)
	at liquibase.Liquibase.lambda$update$1(Liquibase.java:264)
	at liquibase.Scope.lambda$child$0(Scope.java:177)
	at liquibase.Scope.child(Scope.java:186)
	at liquibase.Scope.child(Scope.java:176)
	at liquibase.Scope.child(Scope.java:155)
	at liquibase.Liquibase.runInScope(Liquibase.java:2404)
	at liquibase.Liquibase.update(Liquibase.java:211)
	at liquibase.Liquibase.update(Liquibase.java:197)
	at liquibase.integration.commandline.Main.doMigration(Main.java:1882)
	at liquibase.integration.commandline.Main$1.lambda$run$0(Main.java:402)
	at liquibase.Scope.lambda$child$0(Scope.java:177)
	at liquibase.Scope.child(Scope.java:186)
	at liquibase.Scope.child(Scope.java:176)
	at liquibase.Scope.child(Scope.java:155)
	at liquibase.integration.commandline.Main$1.run(Main.java:401)
	at liquibase.integration.commandline.Main$1.run(Main.java:225)
	at liquibase.Scope.child(Scope.java:186)
	at liquibase.Scope.child(Scope.java:162)
	at liquibase.integration.commandline.Main.run(Main.java:225)
	at liquibase.integration.commandline.Main.main(Main.java:168)
Caused by: liquibase.exception.MigrationFailedException: Migration failed for change set com/company/products/liquibase/changelog/001-products-addon.xml::2::products-addon:
     Reason: liquibase.exception.DatabaseException: user lacks privilege or object not found: PUBLIC.USR_USER [Failed SQL: (-5501) ALTER TABLE PUBLIC.PRD_PRODUCT ADD CONSTRAINT FK_PRD_PRODUCT_ON_MAINTAINER FOREIGN KEY (MAINTAINER_ID) REFERENCES PUBLIC.USR_USER (ID)]
	at liquibase.changelog.ChangeSet.execute(ChangeSet.java:695)
	at liquibase.changelog.visitor.UpdateVisitor.visit(UpdateVisitor.java:49)
	at liquibase.changelog.ChangeLogIterator$2.lambda$null$0(ChangeLogIterator.java:111)
	at liquibase.Scope.lambda$child$0(Scope.java:177)
	at liquibase.Scope.child(Scope.java:186)
	at liquibase.Scope.child(Scope.java:176)
	at liquibase.Scope.child(Scope.java:155)
	at liquibase.changelog.ChangeLogIterator$2.lambda$run$1(ChangeLogIterator.java:110)
	at liquibase.Scope.lambda$child$0(Scope.java:177)
	at liquibase.Scope.child(Scope.java:186)
	at liquibase.Scope.child(Scope.java:176)
	at liquibase.Scope.child(Scope.java:155)
	at liquibase.Scope.child(Scope.java:239)
	at liquibase.changelog.ChangeLogIterator$2.run(ChangeLogIterator.java:94)
	at liquibase.Scope.lambda$child$0(Scope.java:177)
	at liquibase.Scope.child(Scope.java:186)
	at liquibase.Scope.child(Scope.java:176)
	at liquibase.Scope.child(Scope.java:155)
	at liquibase.Scope.child(Scope.java:239)
	at liquibase.Scope.child(Scope.java:243)
	at liquibase.changelog.ChangeLogIterator.run(ChangeLogIterator.java:66)
	... 26 more
Caused by: liquibase.exception.DatabaseException: user lacks privilege or object not found: PUBLIC.USR_USER [Failed SQL: (-5501) ALTER TABLE PUBLIC.PRD_PRODUCT ADD CONSTRAINT FK_PRD_PRODUCT_ON_MAINTAINER FOREIGN KEY (MAINTAINER_ID) REFERENCES PUBLIC.USR_USER (ID)]
	at liquibase.executor.jvm.JdbcExecutor$ExecuteStatementCallback.doInStatement(JdbcExecutor.java:393)
	at liquibase.executor.jvm.JdbcExecutor.execute(JdbcExecutor.java:82)
	at liquibase.executor.jvm.JdbcExecutor.execute(JdbcExecutor.java:150)
	at liquibase.database.AbstractJdbcDatabase.execute(AbstractJdbcDatabase.java:1279)
	at liquibase.database.AbstractJdbcDatabase.executeStatements(AbstractJdbcDatabase.java:1261)
	at liquibase.changelog.ChangeSet.execute(ChangeSet.java:660)
	... 46 more
Caused by: java.sql.SQLSyntaxErrorException: user lacks privilege or object not found: PUBLIC.USR_USER
	at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
	at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
	at org.hsqldb.jdbc.JDBCStatement.fetchResult(Unknown Source)
	at org.hsqldb.jdbc.JDBCStatement.execute(Unknown Source)
	at liquibase.executor.jvm.JdbcExecutor$ExecuteStatementCallback.doInStatement(JdbcExecutor.java:389)
	... 51 more
Caused by: org.hsqldb.HsqlException: user lacks privilege or object not found: PUBLIC.USR_USER
	at org.hsqldb.error.Error.error(Unknown Source)
	at org.hsqldb.error.Error.error(Unknown Source)
	at org.hsqldb.SchemaManager.getUserTable(Unknown Source)
	at org.hsqldb.SchemaManager.getUserTable(Unknown Source)
	at org.hsqldb.ParserDDL.compileAlterTableAddForeignKeyConstraint(Unknown Source)
	at org.hsqldb.ParserDDL.compileAlterTable(Unknown Source)
	at org.hsqldb.ParserDDL.compileAlter(Unknown Source)
	at org.hsqldb.ParserCommand.compilePart(Unknown Source)
	at org.hsqldb.ParserCommand.compileStatements(Unknown Source)
	at org.hsqldb.Session.executeDirectStatement(Unknown Source)
	at org.hsqldb.Session.execute(Unknown Source)
	... 54 more

Just did a fresh clone, opened all in the IDE, and ran it successfully.
Make sure that you open the all subdirectory as written in README.

Yes, the sample application is running as expected.

I tried with my own test application where I did the following but not working:

  1. Moved User entity, user screen from main application to “users” add-on
  2. Moved Secirities folder from main application to “users”
  3. Updated package references but the following preferences couldn’t be resolved:

For User entity:
import io.jmix.security.authentication.JmixUserDetails;

for DatabaseUserRepository in Security:
import io.jmix.securitydata.user.AbstractDatabaseUserRepository;

for FullAccessRole in security:

import io.jmix.security.model.EntityAttributePolicyAction;
import io.jmix.security.model.EntityPolicyAction;
import io.jmix.security.role.annotation.EntityAttributePolicy;
import io.jmix.security.role.annotation.EntityPolicy;
import io.jmix.security.role.annotation.ResourceRole;
import io.jmix.security.role.annotation.SpecificPolicy;
import io.jmix.securityui.role.annotation.MenuPolicy;
import io.jmix.securityui.role.annotation.ScreenPolicy;

I’m surely missing something, would appreciate indicating what is missing here.

the missing package is resolved by updating the security dependencies in each of the modules.
Now I get the following error. Thanks for your support on how we can resolve this.


2022-11-03 13:01:45.325 ERROR 79357 --- [           main] o.s.b.web.embedded.tomcat.TomcatStarter  : Error starting Tomcat context. Exception: org.springframework.beans.factory.UnsatisfiedDependencyException. Message: Error creating bean with name 'io.jmix.security.SecurityConfiguration': Unsatisfied dependency expressed through field 'userRepository'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'io.jmix.core.security.UserRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
2022-11-03 13:01:45.341  INFO 79357 --- [           main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
2022-11-03 13:01:45.344  WARN 79357 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
2022-11-03 13:01:45.351  INFO 79357 --- [           main] ConditionEvaluationReportLoggingListener : 

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2022-11-03 13:01:45.367 ERROR 79357 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 

***************************
APPLICATION FAILED TO START
***************************

Description:

Field userRepository in io.jmix.security.SecurityConfiguration required a bean of type 'io.jmix.core.security.UserRepository' that could not be found.

The injection point has the following annotations:
	- @org.springframework.beans.factory.annotation.Autowired(required=true)


Action:

Consider defining a bean of type 'io.jmix.core.security.UserRepository' in your configuration.


> Task :bootRun FAILED

For some reason the refactoring of user Entity was unsuccessful and SEC tables were gone! After recreating them, moving user to an add-on within my composite FlowUI projects is now working.