这是indexloc提供的服务,不要输入任何密码
Skip to content

Conversation

@wikumChamith
Copy link
Member

No description provided.

@wikumChamith wikumChamith marked this pull request as draft October 1, 2025 09:33
@wikumChamith wikumChamith requested a review from dkayiwa October 1, 2025 09:33
@wikumChamith
Copy link
Member Author

@dkayiwa, @ibacher, any suggestions on how to fix errors like:

The requested URI has more than one handler: /options.form ==> expected: <false> but was: <true>

@wikumChamith wikumChamith force-pushed the 3.x-new branch 2 times, most recently from 947106b to 93606dd Compare October 2, 2025 08:43
</property>
</bean>

<bean parent="obsServiceTarget" >
Copy link
Member

Choose a reason for hiding this comment

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

Do you mind explaining why we removed this?

Copy link
Member Author

Choose a reason for hiding this comment

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

Having this causes an error.

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'obsServiceTarget' available

<!-- Add here beans related to the web context -->

<bean id="legacyUiUrlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="patternParser"><null/></property>
Copy link
Member

Choose a reason for hiding this comment

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

Why add it if the value is null?

Copy link
Member Author

@wikumChamith wikumChamith Oct 4, 2025

Choose a reason for hiding this comment

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

Caused by: org.springframework.web.util.pattern.PatternParseException: No more pattern data allowed after {*...} or ** pattern element

This is a hack I used to avoid PatternParseException.

@ibacher
Copy link
Member

ibacher commented Oct 3, 2025

any suggestions on how to fix errors like

So what's happening is that there are two "org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" beans registered in the context. One we explicitly register here and one that is implicitly registered here by the use of the <mvc:view-controller /> elements in the legacy UI.

The bean we explicitly create gets named org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter#0 but has an alias added of org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter. The bean created implicitly is simply named org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.

I'm not entirely sure what happened, but this commit is part of Spring 6 and it will just remove the implicit alias of org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter from the bean we created.

So a couple of things suggest themselves:

  1. Explicitly name the bean we create org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter via the name attribute on the bean definition.
  2. Remove the <mvc:view-controller /> annotations and find some other way of mapping those things.
  3. Remove our explicit create of the org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter and either add a new Spring @Configuration object annotated @EnableWebMvc in the web project of core.

Personally I think 3 is the cleanest thing, but may require more tweaks, e.g., to ensure that the new @Configuration class is properly loaded in tests.

@wikumChamith
Copy link
Member Author

wikumChamith commented Oct 5, 2025

any suggestions on how to fix errors like

So what's happening is that there are two "org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" beans registered in the context. One we explicitly register here and one that is implicitly registered here by the use of the <mvc:view-controller /> elements in the legacy UI.

The bean we explicitly create gets named org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter#0 but has an alias added of org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter. The bean created implicitly is simply named org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.

I'm not entirely sure what happened, but this commit is part of Spring 6 and it will just remove the implicit alias of org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter from the bean we created.

So a couple of things suggest themselves:

1. Explicitly name the bean we create `org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter` via the `name` attribute on the bean definition.

2. Remove the `<mvc:view-controller />` annotations and find some other way of mapping those things.

3. Remove our explicit create of the `org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter` and _either_ add a new Spring `@Configuration` object annotated `@EnableWebMvc` in the `web` project of core.

Personally I think 3 is the cleanest thing, but may require more tweaks, e.g., to ensure that the new @Configuration class is properly loaded in tests.

@ibacher I tried both 1 and 3. However, I am still seeing the error. Here are the PRs for them.

1:openmrs/openmrs-core#5373
3:openmrs/openmrs-core#5374

@ibacher
Copy link
Member

ibacher commented Oct 8, 2025

Well, I stupidly assumed that the XML stuff wouldn't interfere with the @EnableWebMvc stuff and... that turns out to be false.

@ibacher
Copy link
Member

ibacher commented Oct 8, 2025

Anyways, @wikumChamith I added a commit here and to openmrs/openmrs-core#5374 that fixes that issue in a way I'm happy with. There are still some test failures but they aren't caused by this issue.

Btw, we should take every opportunity available to dump XML Spring configurations if possible. There were some issues with the services wrapped in TransactionProxyFactoryBeans, but we Platform 3, we should be dropping those.

@wikumChamith
Copy link
Member Author

PR to fix test errors on ChangePasswordFormControllerTest: openmrs/openmrs-core#5394

@dkayiwa
Copy link
Member

dkayiwa commented Oct 13, 2025

I put a comment on that pull request.

@wikumChamith
Copy link
Member Author

@dkayiwa, @ibacher, any idea on what is causing the TransientObjectException in ConceptFormControllerTest#shouldVoidShortName?

@dkayiwa
Copy link
Member

dkayiwa commented Oct 25, 2025

@wikumChamith did you eventually figure this out?

@dkayiwa
Copy link
Member

dkayiwa commented Oct 25, 2025

@wikumChamith in that failing test, try changing new Concept() to new Concept(3)

@wikumChamith
Copy link
Member Author

@dkayiwa, @ibacher the module is compiling now, but I’m seeing an error when I run the module:

SEVERE: Servlet.service() for servlet [openmrs] in context with path [/openmrs] threw exception [java.lang.NoClassDefFoundError: javax/servlet/jsp/tagext/TagLibraryValidator] with root cause
java.lang.ClassNotFoundException: javax.servlet.jsp.tagext.TagLibraryValidator
	at org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy.loadClass(SelfFirstStrategy.java:42)
	at org.codehaus.plexus.classworlds.realm.ClassRealm.unsynchronizedLoadClass(ClassRealm.java:225)
	at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:210)
	at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:205)
	at java.base/java.lang.ClassLoader.defineClass1(Native Method)
	at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1027)
	at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150)
	at java.base/java.net.URLClassLoader.defineClass(URLClassLoader.java:524)
	at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:427)
	at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:421)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:714)
	at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:420)
	at org.codehaus.plexus.classworlds.realm.ClassRealm.findClassInternal(ClassRealm.java:256)
	at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClassFromSelf(ClassRealm.java:351)
	at org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy.loadClass(SelfFirstStrategy.java:36)
	at org.codehaus.plexus.classworlds.realm.ClassRealm.unsynchronizedLoadClass(ClassRealm.java:225)
	at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:210)
	at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:205)
	at java.base/java.lang.ClassLoader.defineClass1(Native Method)
	at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1027)
	at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150)
	at java.base/java.net.URLClassLoader.defineClass(URLClassLoader.java:524)
	at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:427)
	at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:421)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:714)
	at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:420)
	at org.codehaus.plexus.classworlds.realm.ClassRealm.findClassInternal(ClassRealm.java:256)
	at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClassFromSelf(ClassRealm.java:351)
	at org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy.loadClass(SelfFirstStrategy.java:36)
	at org.codehaus.plexus.classworlds.realm.ClassRealm.unsynchronizedLoadClass(ClassRealm.java:225)
	at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:210)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:580)
	at org.codehaus.plexus.classworlds.realm.ClassRealm.unsynchronizedLoadClass(ClassRealm.java:222)
	at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:210)
	at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:205)
	at java.base/java.lang.Class.forName0(Native Method)
	at java.base/java.lang.Class.forName(Class.java:534)
	at java.base/java.lang.Class.forName(Class.java:513)
	at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1209)
	at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1059)
	at org.openmrs.util.OpenmrsClassLoader.loadClass(OpenmrsClassLoader.java:165)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
	at org.apache.jasper.compiler.TagLibraryInfoImpl.createValidator(TagLibraryInfoImpl.java:352)
	at org.apache.jasper.compiler.TagLibraryInfoImpl.<init>(TagLibraryInfoImpl.java:192)
	at org.apache.jasper.compiler.Parser.parseTaglibDirective(Parser.java:408)
	at org.apache.jasper.compiler.Parser.parseDirective(Parser.java:461)
	at org.apache.jasper.compiler.Parser.parseElements(Parser.java:1289)
	at org.apache.jasper.compiler.Parser.parse(Parser.java:130)
	at org.apache.jasper.compiler.ParserController.doParse(ParserController.java:243)
	at org.apache.jasper.compiler.ParserController.parse(ParserController.java:146)
	at org.apache.jasper.compiler.Parser.processIncludeDirective(Parser.java:325)
	at org.apache.jasper.compiler.Parser.parseIncludeDirective(Parser.java:362)
	at org.apache.jasper.compiler.Parser.parseDirective(Parser.java:453)
	at org.apache.jasper.compiler.Parser.parseElements(Parser.java:1289)
	at org.apache.jasper.compiler.Parser.parse(Parser.java:130)
	at org.apache.jasper.compiler.ParserController.doParse(ParserController.java:243)
	at org.apache.jasper.compiler.ParserController.parse(ParserController.java:106)
	at org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:195)
	at org.apache.jasper.compiler.Compiler.compile(Compiler.java:368)
	at org.apache.jasper.compiler.Compiler.compile(Compiler.java:346)
	at org.apache.jasper.compiler.Compiler.compile(Compiler.java:332)
	at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:591)
	at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:376)
	at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:337)
	at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:288)
	at org.openmrs.module.web.OpenmrsJspServlet.service(OpenmrsJspServlet.java:51)
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:710)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:130)
	at org.openmrs.web.filter.JspClassLoaderFilter.doFilter(JspClassLoaderFilter.java:47)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:110)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:110)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
	at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:514)
	at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:334)
	at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:263)
	at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:171)
	at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:314)
	at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1438)
	at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1168)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1106)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:622)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:710)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:130)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:110)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:110)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
	at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:514)
	at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:334)
	at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:263)
	at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:171)
	at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:314)
	at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1438)
	at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1168)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1106)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:622)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:710)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:130)
	at org.openmrs.module.web.filter.ForcePasswordChangeFilter.doFilter(ForcePasswordChangeFilter.java:61)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
	at org.openmrs.module.web.filter.RedirectAfterLoginFilter.doFilter(RedirectAfterLoginFilter.java:64)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
	at org.openmrs.web.filter.GZIPFilter.doFilterInternal(GZIPFilter.java:66)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
	at org.openmrs.module.web.filter.ModuleFilterChain.doFilter(ModuleFilterChain.java:73)
	at org.openmrs.web.xss.XSSFilter.doFilter(XSSFilter.java:40)
	at org.openmrs.module.web.filter.ModuleFilterChain.doFilter(ModuleFilterChain.java:71)
	at org.openmrs.module.web.filter.ModuleFilter.doFilter(ModuleFilter.java:57)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
	at org.owasp.csrfguard.CsrfGuardFilter.handleSession(CsrfGuardFilter.java:107)
	at org.owasp.csrfguard.CsrfGuardFilter.doFilter(CsrfGuardFilter.java:97)
	at org.owasp.csrfguard.CsrfGuardFilter.doFilter(CsrfGuardFilter.java:68)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
	at org.openmrs.web.filter.OpenmrsFilter.doFilterInternal(OpenmrsFilter.java:114)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
	at org.openmrs.web.filter.CookieClearingFilter.doFilterInternal(CookieClearingFilter.java:77)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
	at org.springframework.orm.hibernate5.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:155)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
	at org.springframework.web.multipart.support.MultipartFilter.doFilterInternal(MultipartFilter.java:125)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
	at org.openmrs.web.filter.StartupFilter.doFilter(StartupFilter.java:120)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
	at org.openmrs.web.filter.StartupFilter.doFilter(StartupFilter.java:120)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
	at org.openmrs.web.filter.StartupFilter.doFilter(StartupFilter.java:120)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:79)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:116)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:396)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:903)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1773)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:59)
	at java.base/java.lang.Thread.run(Thread.java:1583)

To resolve this, I removed the taglib dependencies from core and used org.glassfish.web:jakarta.servlet.jsp.jstl in this module. However, I’m still seeing the same error. We’re currently using the JstlCoreTLV validator, but since it now uses Jakarta EE, removing it didn’t fix the issue either.

Is there anywhere else that might still be using a javax-era taglib that I may have missed?

@dkayiwa
Copy link
Member

dkayiwa commented Oct 27, 2025

@wikumChamith did you figure this out?

@wikumChamith
Copy link
Member Author

@wikumChamith did you figure this out?

Nope, still trying to sort it out. Any suggestions??

@wikumChamith wikumChamith requested a review from dkayiwa October 28, 2025 10:39
Concept concept = cs.getConcept(5497);
//sanity check, the current preferred Name should be different from what will get set in the form
Assert.assertNotSame("CD3+CD4+ABS CNT", concept.getPreferredName(britishEn).getName());
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 did not use a different pull request for these formatting changes?

ProgramFormController controller = (ProgramFormController) applicationContext.getBean("programForm");
controller.handleRequest(request, new MockHttpServletResponse());

Context.clearSession();
Copy link
Member

Choose a reason for hiding this comment

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

What failure is the above addressing?

@dkayiwa
Copy link
Member

dkayiwa commented Oct 28, 2025

@wikumChamith because org.apache.taglibs.standard.tlv.JstlCoreTLV does not have a corresponding jakarta implementation, can you just remove the whole validator element? https://github.com/openmrs/openmrs-module-legacyui/blob/1.23.0/omod/src/main/webapp/taglibs/c-rt.tld#L13-L20

@wikumChamith
Copy link
Member Author

@wikumChamith because org.apache.taglibs.standard.tlv.JstlCoreTLV does not have a corresponding jakarta implementation, can you just remove the whole validator element? https://github.com/openmrs/openmrs-module-legacyui/blob/1.23.0/omod/src/main/webapp/taglibs/c-rt.tld#L13-L20

@dkayiwa, that also gives a similar error:

java.lang.ClassNotFoundException: javax.servlet.jsp.tagext.TagExtraInfo
	at org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy.loadClass(SelfFirstStrategy.java:42)
	at org.codehaus.plexus.classworlds.realm.ClassRealm.unsynchronizedLoadClass(ClassRealm.java:225)
	at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:210)
	at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:205)
	at java.base/java.lang.ClassLoader.defineClass1(Native Method)
	at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1027)
	at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150)
	at java.base/java.net.URLClassLoader.defineClass(URLClassLoader.java:524)
	at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:427)
	at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:421)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:714)
	at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:420)
	at org.codehaus.plexus.classworlds.realm.ClassRealm.findClassInternal(ClassRealm.java:256)
	at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClassFromSelf(ClassRealm.java:351)
	at org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy.loadClass(SelfFirstStrategy.java:36)
	at org.codehaus.plexus.classworlds.realm.ClassRealm.unsynchronizedLoadClass(ClassRealm.java:225)
	at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:210)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:580)
	at org.codehaus.plexus.classworlds.realm.ClassRealm.unsynchronizedLoadClass(ClassRealm.java:222)
	at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:210)
	at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:205)
	at java.base/java.lang.Class.forName0(Native Method)
	at java.base/java.lang.Class.forName(Class.java:534)
	at java.base/java.lang.Class.forName(Class.java:513)
	at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1209)
	at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1059)
	at org.openmrs.util.OpenmrsClassLoader.loadClass(OpenmrsClassLoader.java:165)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
	at org.apache.jasper.compiler.TagLibraryInfoImpl.createTagInfo(TagLibraryInfoImpl.java:299)
	at org.apache.jasper.compiler.TagLibraryInfoImpl.<init>(TagLibraryInfoImpl.java:196)
	at org.apache.jasper.compiler.Parser.parseTaglibDirective(Parser.java:408)
	at org.apache.jasper.compiler.Parser.parseDirective(Parser.java:461)
	at org.apache.jasper.compiler.Parser.parseElements(Parser.java:1289)
	at org.apache.jasper.compiler.Parser.parse(Parser.java:130)
	at org.apache.jasper.compiler.ParserController.doParse(ParserController.java:243)
	at org.apache.jasper.compiler.ParserController.parse(ParserController.java:146)
	at org.apache.jasper.compiler.Parser.processIncludeDirective(Parser.java:325)
	at org.apache.jasper.compiler.Parser.parseIncludeDirective(Parser.java:362)
	at org.apache.jasper.compiler.Parser.parseDirective(Parser.java:453)
	at org.apache.jasper.compiler.Parser.parseElements(Parser.java:1289)
	at org.apache.jasper.compiler.Parser.parse(Parser.java:130)
	at org.apache.jasper.compiler.ParserController.doParse(ParserController.java:243)
	at org.apache.jasper.compiler.ParserController.parse(ParserController.java:106)
	at org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:195)
	at org.apache.jasper.compiler.Compiler.compile(Compiler.java:368)
	at org.apache.jasper.compiler.Compiler.compile(Compiler.java:346)
	at org.apache.jasper.compiler.Compiler.compile(Compiler.java:332)
	at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:591)
	at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:376)
	at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:337)
	at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:288)
	at org.openmrs.module.web.OpenmrsJspServlet.service(OpenmrsJspServlet.java:51)
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:710)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:130)
	at org.openmrs.web.filter.JspClassLoaderFilter.doFilter(JspClassLoaderFilter.java:47)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:110)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:110)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
	at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:514)
	at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:334)
	at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:263)
	at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:171)
	at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:314)
	at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1438)
	at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1168)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1106)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:622)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:710)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:130)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:110)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:110)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
	at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:514)
	at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:334)
	at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:263)
	at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:171)
	at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:314)
	at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1438)
	at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1168)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1106)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:622)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:710)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:130)
	at org.openmrs.module.web.filter.ForcePasswordChangeFilter.doFilter(ForcePasswordChangeFilter.java:61)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
	at org.openmrs.module.web.filter.RedirectAfterLoginFilter.doFilter(RedirectAfterLoginFilter.java:64)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
	at org.openmrs.web.filter.GZIPFilter.doFilterInternal(GZIPFilter.java:66)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
	at org.openmrs.module.web.filter.ModuleFilterChain.doFilter(ModuleFilterChain.java:73)
	at org.openmrs.web.xss.XSSFilter.doFilter(XSSFilter.java:40)
	at org.openmrs.module.web.filter.ModuleFilterChain.doFilter(ModuleFilterChain.java:71)
	at org.openmrs.module.web.filter.ModuleFilter.doFilter(ModuleFilter.java:57)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
	at org.owasp.csrfguard.CsrfGuardFilter.handleSession(CsrfGuardFilter.java:107)
	at org.owasp.csrfguard.CsrfGuardFilter.doFilter(CsrfGuardFilter.java:97)
	at org.owasp.csrfguard.CsrfGuardFilter.doFilter(CsrfGuardFilter.java:68)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
	at org.openmrs.web.filter.OpenmrsFilter.doFilterInternal(OpenmrsFilter.java:114)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
	at org.openmrs.web.filter.CookieClearingFilter.doFilterInternal(CookieClearingFilter.java:77)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
	at org.springframework.orm.hibernate5.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:155)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
	at org.springframework.web.multipart.support.MultipartFilter.doFilterInternal(MultipartFilter.java:125)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
	at org.openmrs.web.filter.StartupFilter.doFilter(StartupFilter.java:120)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
	at org.openmrs.web.filter.StartupFilter.doFilter(StartupFilter.java:120)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
	at org.openmrs.web.filter.StartupFilter.doFilter(StartupFilter.java:120)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:79)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:116)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:396)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:903)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1773)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:59)
	at java.base/java.lang.Thread.run(Thread.java:1583)

I also tried deleting all the tld files. However, that didn't resolved the issue.

@dkayiwa
Copy link
Member

dkayiwa commented Oct 29, 2025

Even after removing the validator?

@wikumChamith
Copy link
Member Author

Even after removing the validator?

Yes

@dkayiwa
Copy link
Member

dkayiwa commented Oct 29, 2025

Can you open a pull request for the changes you did in core for this?

@wikumChamith
Copy link
Member Author

Can you open a pull request for the changes you did in core for this?

@dkayiwa PR: openmrs/openmrs-core#5441

@dkayiwa
Copy link
Member

dkayiwa commented Oct 29, 2025

How are you running it? I seem to be getting a different error: org.apache.jasper.JasperException: /WEB-INF/view/index.jsp (line: [1], column: [1]) Failed to load or instantiate TagExtraInfo class: [org.apache.taglibs.page.AttributesTEI]

@wikumChamith
Copy link
Member Author

How are you running it? I seem to be getting a different error: org.apache.jasper.JasperException: /WEB-INF/view/index.jsp (line: [1], column: [1]) Failed to load or instantiate TagExtraInfo class: [org.apache.taglibs.page.AttributesTEI]

I tried running it with both the SDK and cargo:run from openmrs-core.

@wikumChamith
Copy link
Member Author

Yeah, I tried with Claude, but it just kept suggesting random changes :)

I decided to set Spring’s log level to DEBUG and noticed this:

DEBUG - AbstractView.render(307) |2025-11-12T16:46:59,867| View name [/scripts/jquery-ui/js/jquery-ui-timepicker-month-year-patch.js], model {}
DEBUG - InternalResourceView.renderMergedOutputModel(169) |2025-11-12T16:46:59,868| Forwarding to [/WEB-INF/view//scripts/jquery-ui/js/jquery-ui-timepicker-month-year-patch.js.jsp]

The forwarding path has a double slash (/WEB-INF/view//scripts/), which is likely causing the issue.

What I’m wondering now is why we have the jspViewResolver and urlMapping beans declared twice, once in WebConfig (moved from openmrs-servlet.xml) and again in openmrs_static_content-servlet.xml.
Is there a specific reason for that?

cc: @dkayiwa @ibacher

@dkayiwa
Copy link
Member

dkayiwa commented Nov 12, 2025

@wikumChamith aren't you the one who duplicated them? 😊

@wikumChamith
Copy link
Member Author

@wikumChamith aren't you the one who duplicated them? 😊

No, the duplication was already there. I only moved the beans from openmrs-servlet.xml to WebConfig. Here’s the proof from 2.8.x:

@dkayiwa
Copy link
Member

dkayiwa commented Nov 12, 2025

Do they deal with the same suffix?

@wikumChamith
Copy link
Member Author

No, that’s why I’m wondering why both beans have the same name :)

@dkayiwa
Copy link
Member

dkayiwa commented Nov 12, 2025

Change the name and see what happens. 😊

@wikumChamith
Copy link
Member Author

Change the name and see what happens. 😊

Nothing changes and I’m still getting the same error. From the logs, you can see .jsp is being appended to .js requests:

DEBUG - InternalResourceView.renderMergedOutputModel(169) |2025-11-12T16:46:59,868| Forwarding to [/WEB-INF/view/scripts/jquery-ui/js/jquery-ui-timepicker-month-year-patch.js.jsp]

So it looks like these requests are going through the jspViewResolver in WebConfig :)

@wikumChamith
Copy link
Member Author

@dkayiwa what is the reason for the force push :) ?

@dkayiwa
Copy link
Member

dkayiwa commented Nov 12, 2025

@wikumChamith i just clicked the update branch button 😊

@ibacher
Copy link
Member

ibacher commented Nov 14, 2025

now is why we have the jspViewResolver and urlMapping beans declared twice

This would be the case, but only within the scope of the openmrs_static_content servlet. It isn't part of our contextConfigLocation, so it must be loaded implicitly when the DispatcherServlet instance is initialized. Each DispatcherServlet "will operate in its own namespace, loading its own application context with mappings, handlers, etc.", i.e., each DispatcherServlet creates its own child WebApplicationContext.

Not sure what to suggest here. We could try:

  1. Removing the order attribute from the bean in the WebConfig
  2. Reworking things so that the WebConfig (or at least the stuff like the jspViewResolver and urlMapping) are only loaded in the context of the openmrs_servlet DispatcherServlet.
  3. Some other clever idea...

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.

3 participants