Skip to content

Conversation

@wikumChamith
Copy link
Member

@wikumChamith wikumChamith commented Jul 16, 2025

@wikumChamith wikumChamith marked this pull request as draft July 16, 2025 14:57
@wikumChamith wikumChamith marked this pull request as ready for review July 22, 2025 05:26
@wikumChamith
Copy link
Member Author

@dkayiwa, why are we seeing a forbidden class exception even though the MetadataPackagesConfig class is on the whitelisting list?

<globalProperty>
<property>emrapi.serializer.whitelist.types</property>
<defaultValue>org.openmrs.module.emrapi.metadata.MetadataPackagesConfig,org.openmrs.module.emrapi.metadata.MetadataPackageConfig</defaultValue>
<description></description>
</globalProperty>

public void setProviderRole(Provider provider, ProviderRole providerRole) {
provider.setProviderRole(providerRole);
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be able to delete this class, no?


void setProviderRole(Provider provider, Object providerRole);
void setProviderRole(Provider provider, ProviderRole providerRole);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be able to delete this class, no?

import static org.openmrs.util.OpenmrsConstants.USER_PROPERTY_LOGIN_ATTEMPTS;

public class AccountDomainWrapperTest extends EmrApiContextSensitiveTest {
public class AccountDomainWrapperTest extends BaseModuleContextSensitiveTest {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you are going to switch from EmrApiContextSensitiveTest to BaseModuleContextSensitiveTest, why aren't you deleting the (now empty) EmrApiContextSensitiveTest. Any reason not to keep it around and use it even if it is empty? Gives a convenient place to put code that you need to execute for every test in this module.

providerManagementService = mock(ProviderManagementService.class);
providerServiceFacade = new MockProviderServiceFacade(new ProviderManagementProviderService(providerService, providerManagementService));
providerManagementService = mock(ProviderService.class);
providerServiceFacade = new MockProviderServiceFacade(new CoreProviderService(providerService));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This entire providerServiceFacade idea is no longer needed. Just remove it and use providerService directly


providerIdentifierGenerator = mock(ProviderIdentifierGenerator.class);
when(providerIdentifierGenerator.generateIdentifier(any(Provider.class))).thenReturn("456");
lenient().when(providerIdentifierGenerator.generateIdentifier(any(Provider.class))).thenReturn("456");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do these lenient() calls do?

<argLine>-Xmx512m -XX:MaxPermSize=512m -Djdk.net.URLClassPath.disableClassPathURLCheck=true</argLine>
<includes>
<include>**/*Test.java</include>
<include>**/*_IT.java</include>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just want to confirm that after removing this that all tests are still executed (eg all _IT tests)

@wikumChamith
Copy link
Member Author

@mseaton I updated the PR according to your suggestions. Do you know why I am getting the xstream.security.ForbiddenClassException in MetadataUtilTest ?

@wikumChamith
Copy link
Member Author

Should I remove the MetadataUtilTest, since MetadataUtil has been deprecated and its functionality has been moved to the Metadata Sharing module?

@mseaton
Copy link
Member

mseaton commented Jul 23, 2025

Should I remove the MetadataUtilTest, since MetadataUtil has been deprecated and its functionality has been moved to the Metadata Sharing module?

I think this is fine @wikumChamith . If you do so, please also remove MetadataUtil. It has been deprecated for a long time, and in any event this new change you are introducing definitely requires a new major version anyway.

So please update this PR to change the version in the pom to 3.0.0-SNAPSHOT.

(I am doing a release from the master branch now which will be 2.4.0, and we can fork off from there as needed as a maintenance branch for those that cannot move to 2.8.x in the near term)

Copy link
Member

@mseaton mseaton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM (though I don't know about the changes to the findPatient DAO, I didn't review these in detail and don't have a good sense of why they are required)

@wikumChamith
Copy link
Member Author

LGTM (though I don't know about the changes to the findPatient DAO, I didn't review these in detail and don't have a good sense of why they are required)

PatientSearchCriteria has been deprecated, and this was showing some errors. So, I decided to replace it with the JPA Criteria API, which is the recommended approach starting from Platform 2.7.0.

@dkayiwa
Copy link
Member

dkayiwa commented Jul 27, 2025

@wikumChamith did you get a chance to look at the build errors?

@wikumChamith
Copy link
Member Author

wikumChamith commented Jul 28, 2025

@wikumChamith did you get a chance to look at the build errors?

@dkayiwa Looks like these errors are coming from core, specifically after this commit: openmrs/openmrs-core@ec1f42c

cc: @rkorytkowski

@rkorytkowski
Copy link
Member

The issue is TestingApplicationContext overrides sessionFactory from core and doesn't set cacheConfig property. I think I need to move cacheConfig to be autowired again in case of this kind of overwrite... Overwriting bean definition is hacky and we will want to come up with some better approach here. I'll think about it.

@rkorytkowski
Copy link
Member

rkorytkowski commented Jul 28, 2025

Reverted to use @Autowired in openmrs/openmrs-core@77de212 Once CI build completes, we can rerun tests.

@dkayiwa
Copy link
Member

dkayiwa commented Jul 28, 2025

@rkorytkowski are we reverting simply for tests? How about making tests hack this out without having to revert the changes in core, if they were for the better running of the application?

@wikumChamith
Copy link
Member Author

The issue is TestingApplicationContext overrides sessionFactory from core and doesn't set cacheConfig property. I think I need to move cacheConfig to be autowired again in case of this kind of overwrite... Overwriting bean definition is hacky and we will want to come up with some better approach here. I'll think about it.

Is this a feature or a bug?

@rkorytkowski
Copy link
Member

My change in Autowired doesn't improve anything in core. It was a leftover after experimenting with code that I didn't think would impact anything... but life can't be that predictable. I reverted the change. Another thing is that overwriting sessionFactory as many modules do in TestingApplicationContext isn't the best approach so we could think of a cleaner idea.

@wikumChamith
Copy link
Member Author

My change in Autowired doesn't improve anything in core. It was a leftover after experimenting with code that I didn't think would impact anything... but life can't be that predictable. I reverted the change. Another thing is that overwriting sessionFactory as many modules do in TestingApplicationContext isn't the best approach so we could think of a cleaner idea.

@rkorytkowski, now we are getting a different error.

[INFO] Running org.openmrs.module.emrapi.adt.reporting.evaluator.MostRecentAdmissionRequestVisitDataEvaluatorTest
Warning:  661| ISPN000554: jboss-marshalling is deprecated and planned for removal
Warning:  161| ISPN000554: jboss-marshalling is deprecated and planned for removal
Warning:  863| Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'reportingSerializedDefinitionService' defined in URL [jar:file:/home/runner/.m2/repository/org/openmrs/module/reporting-api/1.25.0/reporting-api-1.25.0.jar!/moduleApplicationContext.xml]: Cannot create inner bean 'org.openmrs.module.reporting.definition.service.SerializedDefinitionServiceImpl#6d709a91' of type [org.openmrs.module.reporting.definition.service.SerializedDefinitionServiceImpl] while setting bean property 'target'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.openmrs.module.reporting.definition.service.SerializedDefinitionServiceImpl#6d709a91' defined in URL [jar:file:/home/runner/.m2/repository/org/openmrs/module/reporting-api/1.25.0/reporting-api-1.25.0.jar!/moduleApplicationContext.xml]: Initialization of bean failed; nested exception is org.spri
java.lang.NullPointerException
	at org.openmrs.api.context.ServiceContext.getRegisteredComponents(ServiceContext.java:921)
	at org.openmrs.api.context.ServiceContext.getRegisteredComponents(ServiceContext.java:889)
	at org.openmrs.api.context.Context.getRegisteredComponents(Context.java:1314)
	at org.openmrs.module.emrapi.encounter.EmrEncounterServiceImpl.onStartup(EmrEncounterServiceImpl.java:99)
	at org.openmrs.module.emrapi.encounter.EmrEncounterServiceImpl$$FastClassBySpringCGLIB$$30c7b921.invoke(<generated>)
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:792)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:762)
	at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:762)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:707)
	at org.openmrs.module.emrapi.encounter.EmrEncounterServiceImpl$$EnhancerBySpringCGLIB$$fd9f2812.onStartup(<generated>)
	at sun.reflect.GeneratedMethodAccessor91.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
	at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.openmrs.aop.LoggingAdvice.invoke(LoggingAdvice.java:123)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:58)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:58)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:241)
	at com.sun.proxy.$Proxy250.onStartup(Unknown Source)
	at org.openmrs.api.context.Daemon.lambda$runInDaemonThreadInternal$5(Daemon.java:452)
	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:750)

@wikumChamith
Copy link
Member Author

My change in Autowired doesn't improve anything in core. It was a leftover after experimenting with code that I didn't think would impact anything... but life can't be that predictable. I reverted the change. Another thing is that overwriting sessionFactory as many modules do in TestingApplicationContext isn't the best approach so we could think of a cleaner idea.

@rkorytkowski, now we are getting a different error.

[INFO] Running org.openmrs.module.emrapi.adt.reporting.evaluator.MostRecentAdmissionRequestVisitDataEvaluatorTest
Warning:  661| ISPN000554: jboss-marshalling is deprecated and planned for removal
Warning:  161| ISPN000554: jboss-marshalling is deprecated and planned for removal
Warning:  863| Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'reportingSerializedDefinitionService' defined in URL [jar:file:/home/runner/.m2/repository/org/openmrs/module/reporting-api/1.25.0/reporting-api-1.25.0.jar!/moduleApplicationContext.xml]: Cannot create inner bean 'org.openmrs.module.reporting.definition.service.SerializedDefinitionServiceImpl#6d709a91' of type [org.openmrs.module.reporting.definition.service.SerializedDefinitionServiceImpl] while setting bean property 'target'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.openmrs.module.reporting.definition.service.SerializedDefinitionServiceImpl#6d709a91' defined in URL [jar:file:/home/runner/.m2/repository/org/openmrs/module/reporting-api/1.25.0/reporting-api-1.25.0.jar!/moduleApplicationContext.xml]: Initialization of bean failed; nested exception is org.spri
java.lang.NullPointerException
	at org.openmrs.api.context.ServiceContext.getRegisteredComponents(ServiceContext.java:921)
	at org.openmrs.api.context.ServiceContext.getRegisteredComponents(ServiceContext.java:889)
	at org.openmrs.api.context.Context.getRegisteredComponents(Context.java:1314)
	at org.openmrs.module.emrapi.encounter.EmrEncounterServiceImpl.onStartup(EmrEncounterServiceImpl.java:99)
	at org.openmrs.module.emrapi.encounter.EmrEncounterServiceImpl$$FastClassBySpringCGLIB$$30c7b921.invoke(<generated>)
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:792)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:762)
	at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:762)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:707)
	at org.openmrs.module.emrapi.encounter.EmrEncounterServiceImpl$$EnhancerBySpringCGLIB$$fd9f2812.onStartup(<generated>)
	at sun.reflect.GeneratedMethodAccessor91.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
	at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.openmrs.aop.LoggingAdvice.invoke(LoggingAdvice.java:123)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:58)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:58)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:241)
	at com.sun.proxy.$Proxy250.onStartup(Unknown Source)
	at org.openmrs.api.context.Daemon.lambda$runInDaemonThreadInternal$5(Daemon.java:452)
	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:750)

I missed this: openmrs/openmrs-module-reporting@ac35bc7

for (int i = 0; i < len; i++) {
char c = localeString.charAt(i);
// allow only ASCII letters and "_" character
if ((c <= 0x20 || c >= 0x7f) || ((c >= 0x20 || c <= 0x7f) && (!Character.isLetter(c) && c != 0x5f))) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason why you dropped ((c >= 0x20 || c <= 0x7f)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is always true in here.

@dkayiwa
Copy link
Member

dkayiwa commented Jul 30, 2025

Does this compile on Java 21?

.distinct(true);

TypedQuery<Patient> typed = em.createQuery(cq);
if (start != null) typed.setFirstResult(start);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


}

private Criteria buildCriteria(String query, Criteria criteria) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did we get rid of this one?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PatientSearchCriteria is deprecated. The same logic is now inside the findPatients method.


if (StringUtils.isNotBlank(query)) {
	if (query.matches(".*\\d.*")) {
		Join<Patient, PatientIdentifier> ids = patient.join("identifiers", JoinType.LEFT);
		preds.add(cb.like(cb.lower(ids.get("identifier")),
				"%" + query.toLowerCase() + "%"));
	} else {
		Join<Patient, PersonName> names = patient.join("names");
		String like = "%" + query.toLowerCase() + "%";
		preds.add(cb.or(cb.like(cb.lower(names.get("givenName")),  like),
				cb.like(cb.lower(names.get("familyName")), like)));
	}
}

@wikumChamith
Copy link
Member Author

Does this compile on Java 21?

No. There are some modules that this depends on that do not yet support Java 21.

@dkayiwa
Copy link
Member

dkayiwa commented Jul 31, 2025

Can't we do as for other modules that we have given support for all the way from Java 8 to 21?

@dkayiwa dkayiwa merged commit 0e7f899 into openmrs:master Aug 10, 2025
1 check passed
@@ -1,341 +0,0 @@
/**
* The contents of this file are subject to the OpenMRS Public License
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wikumChamith why did we delete this file?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

org.openmrs.module.ModuleException: Unable to start OpenMRS. Error thrown was: org/openmrs/module/emrapi/utils/MetadataUtil

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is deprecated and this class also caused an error.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

org.openmrs.module.ModuleException: Unable to start OpenMRS. Error thrown was: org/openmrs/module/emrapi/utils/MetadataUtil

In which module?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When starting O2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants