Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BROKEN >= 7.0.4 Causes Resource Controllers to Render as Content-Type: application/xhtml #303

Closed
codeconsole opened this issue Jul 21, 2021 · 14 comments

Comments

@codeconsole
Copy link
Contributor

Changing a working app from

implementation "org.grails.plugins:hibernate5:7.0.3

to any version >= 7.0.4 results in Resources controllers rendered as:

Content-Type: application/xhtml+xml;charset=UTF-8

and the browser no longer displays them properly.

Using any version <= 7.0.3 results in controllers rendering pages as

Content-Type: text/html;charset=UTF-8

What changed with this plugin between 7.0.3 to 7.0.4 that affected choosing the correct mime type??

https://github.com/grails/grails-data-mapping/compare/v7.0.3..v7.0.4

https://github.com/grails/grails-data-mapping/compare/v7.0.3..7.0.4

And which tag represent 7.0.4 that is in https://repo.grails.org/grails/core/org/grails/plugins/hibernate5/7.0.4/ ?

@codeconsole codeconsole changed the title BROKEN >= 7.0.4 Causes Resource Controllers to Render as BROKEN >= 7.0.4 Causes Resource Controllers to Render as Content-Type: application/xhtml Jul 21, 2021
@codeconsole
Copy link
Contributor Author

codeconsole commented Jul 23, 2021

https://github.com/grails/grails-core/blob/master/grails-plugin-rest/src/main/groovy/grails/artefact/controller/RestResponder.groovy#L150

Stepping into with a debugger, I am finding using 7.0.3

response.mimeTypesFormatAware is equal to one MimeType { name=/,extension=all,parameters=[q:1.0] }

but when I switch to 7.0.4
implementation "org.grails.plugins:hibernate5:7.0.4"

response.mimeTypesFormatAware is equal to 6 MimeTypes and the first one is being used:
Note there is no extension=all in any of them.

MimeType { name=application/xhtml+xml,extension=html,parameters=[q:1.0] }
MimeType { name=text/html,extension=html,parameters=[q:1.0] }
MimeType { name=application/xml,extension=xml,parameters=[q:1.0] }
MimeType { name=text/xml,extension=xml,parameters=[q:1.0] }
MimeType { name=application/json,extension=json,parameters=[q:1.0] }
MimeType { name=text/json,extension=json,parameters=[q:1.0] }

Digging deeper:

webRequest.response.contentType is set here

https://github.com/grails/grails-core/blob/master/grails-plugin-rest/src/main/groovy/grails/artefact/controller/RestResponder.groovy#L216

from

https://github.com/grails/grails-core/blob/master/grails-plugin-rest/src/main/groovy/org/grails/plugins/web/rest/render/html/DefaultHtmlRenderer.groovy#L61

which comes from context.acceptMimeType which comes from webRequest.response.mimeType

https://github.com/grails/grails-core/blob/master/grails-plugin-rest/src/main/groovy/org/grails/plugins/web/rest/render/ServletRenderContext.groovy#L87

which appears to be set here after WebUtils.storeGrailsWebRequest(webRequest); is called
https://github.com/grails/grails-core/blob/master/grails-web-mvc/src/main/groovy/org/grails/web/servlet/mvc/GrailsWebRequestFilter.java#L65

webRequest.response.mimeType = MimeType { name=application/xhtml+xml,extension=html,parameters=[q:1.0] }

Any idea how exactly webRequest.response.mimeType gets called when WebUtils.storeGrailsWebRequest(webRequest); is executed?

@codeconsole
Copy link
Contributor Author

codeconsole commented Jul 24, 2021

I built the same app as an executable jar using 7.0.3 and 7.0.4 and ran both of them. Only 7.0.4 experienced the issue.
I did a diff between the 2 jars of the file contents to see if there was a transitive dependency perhaps causing the issue. The only difference on the contents was:

<     testing: BOOT-INF/lib/hibernate5-7.0.3.jar   OK
---
>     testing: BOOT-INF/lib/hibernate5-7.0.4.jar   OK

I also ran a grails dependencyReport on the 2 configurations which also resulted in the same result.

Apparently I was looking at the wrong code base.

The breaking changes are here:

https://github.com/grails/gorm-hibernate5/compare/v7.0.3..v7.0.4

Archive:  /BOOT-INF/lib/hibernate5-7.0.3.jar
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  04-03-2020 17:10   META-INF/
       25  04-03-2020 17:10   META-INF/MANIFEST.MF
        0  04-03-2020 17:10   grails/
        0  04-03-2020 17:10   grails/orm/
        0  04-03-2020 17:10   grails/orm/bootstrap/
    15054  04-03-2020 17:10   grails/orm/bootstrap/HibernateDatastoreSpringInitializer.class
     2801  04-03-2020 17:10   grails/orm/bootstrap/HibernateDatastoreSpringInitializer$_getBeanDefinitions_closure1$_closure3.class
     8733  04-03-2020 17:10   grails/orm/bootstrap/HibernateDatastoreSpringInitializer$_getBeanDefinitions_closure1.class
     2876  04-03-2020 17:10   grails/orm/bootstrap/HibernateDatastoreSpringInitializer$_getBeanDefinitions_closure1$_closure2.class
        0  04-03-2020 17:10   grails/plugin/
        0  04-03-2020 17:10   grails/plugin/hibernate/
        0  04-03-2020 17:10   grails/plugin/hibernate/commands/
    10886  04-03-2020 17:10   grails/plugin/hibernate/commands/SchemaExportCommand.class
     1692  04-03-2020 17:10   grails/plugin/hibernate/HibernateGrailsPlugin$_doWithSpring_closure1$_closure2.class
     4359  04-03-2020 17:10   grails/plugin/hibernate/HibernateGrailsPlugin$1.class
     6852  04-03-2020 17:10   grails/plugin/hibernate/HibernateGrailsPlugin.class
     3258  04-03-2020 17:10   grails/plugin/hibernate/Application.class
     4641  04-03-2020 17:10   grails/plugin/hibernate/HibernateGrailsPlugin$_doWithSpring_closure1.class
        0  04-03-2020 17:10   grails/test/
        0  04-03-2020 17:10   grails/test/hibernate/
     2262  04-03-2020 17:10   grails/test/hibernate/HibernateSpec$_setupSpec_closure3.class
     2285  04-03-2020 17:10   grails/test/hibernate/HibernateSpec$_canLoadFileExtension_closure6.class
     2259  04-03-2020 17:10   grails/test/hibernate/HibernateSpec$_setupSpec_closure1.class
    11982  04-03-2020 17:10   grails/test/hibernate/HibernateSpec.class
     2392  04-03-2020 17:10   grails/test/hibernate/HibernateSpec$_setupSpec_closure2.class
     1733  04-03-2020 17:10   grails/test/hibernate/HibernateSpec$_canLoadFileExtension_closure5.class
     2392  04-03-2020 17:10   grails/test/hibernate/HibernateSpec$_setupSpec_closure4.class
        0  04-03-2020 17:10   org/
        0  04-03-2020 17:10   org/grails/
        0  04-03-2020 17:10   org/grails/plugin/
        0  04-03-2020 17:10   org/grails/plugin/hibernate/
        0  04-03-2020 17:10   org/grails/plugin/hibernate/support/
     8432  04-03-2020 17:10   org/grails/plugin/hibernate/support/HibernatePersistenceContextInterceptor.class
     1395  04-03-2020 17:10   org/grails/plugin/hibernate/support/AggregatePersistenceContextInterceptor.class
     3148  04-03-2020 17:10   org/grails/plugin/hibernate/support/GrailsOpenSessionInViewInterceptor.class
     4378  04-03-2020 17:10   org/grails/plugin/hibernate/support/AbstractMultipleDataSourceAggregatePersistenceContextInterceptor.class
      341  04-03-2020 17:10   org/grails/plugin/hibernate/support/SessionFactoryAwarePersistenceContextInterceptor.class
     1037  04-03-2020 17:10   META-INF/grails-plugin.xml
      145  04-03-2020 17:10   META-INF/grails.factories
---------                     -------
   105358                     39 files
Archive:  /BOOT-INF/lib/hibernate5-7.0.4.jar
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  07-13-2020 04:23   META-INF/
       25  07-13-2020 04:23   META-INF/MANIFEST.MF
        0  07-13-2020 04:23   grails/
        0  07-13-2020 04:23   grails/orm/
        0  07-13-2020 04:23   grails/orm/bootstrap/
    15054  07-13-2020 04:23   grails/orm/bootstrap/HibernateDatastoreSpringInitializer.class
     3556  07-13-2020 04:23   grails/orm/bootstrap/HibernateDatastoreSpringInitializer$_getBeanDefinitions_closure1$_closure3.class
     2801  07-13-2020 04:23   grails/orm/bootstrap/HibernateDatastoreSpringInitializer$_getBeanDefinitions_closure1$_closure4.class
     8784  07-13-2020 04:23   grails/orm/bootstrap/HibernateDatastoreSpringInitializer$_getBeanDefinitions_closure1.class
     2876  07-13-2020 04:23   grails/orm/bootstrap/HibernateDatastoreSpringInitializer$_getBeanDefinitions_closure1$_closure2.class
     3362  07-13-2020 04:23   grails/orm/bootstrap/HibernateDatastoreSpringInitializer$_getBeanDefinitions_closure1$_closure3$_closure5.class
        0  07-13-2020 04:23   grails/plugin/
        0  07-13-2020 04:23   grails/plugin/hibernate/
        0  07-13-2020 04:23   grails/plugin/hibernate/commands/
    10886  07-13-2020 04:23   grails/plugin/hibernate/commands/SchemaExportCommand.class
     1692  07-13-2020 04:23   grails/plugin/hibernate/HibernateGrailsPlugin$_doWithSpring_closure1$_closure2.class
     4359  07-13-2020 04:23   grails/plugin/hibernate/HibernateGrailsPlugin$1.class
     6852  07-13-2020 04:23   grails/plugin/hibernate/HibernateGrailsPlugin.class
     3258  07-13-2020 04:23   grails/plugin/hibernate/Application.class
     4641  07-13-2020 04:23   grails/plugin/hibernate/HibernateGrailsPlugin$_doWithSpring_closure1.class
        0  07-13-2020 04:23   grails/test/
        0  07-13-2020 04:23   grails/test/hibernate/
     2262  07-13-2020 04:23   grails/test/hibernate/HibernateSpec$_setupSpec_closure3.class
     2285  07-13-2020 04:23   grails/test/hibernate/HibernateSpec$_canLoadFileExtension_closure6.class
     2259  07-13-2020 04:23   grails/test/hibernate/HibernateSpec$_setupSpec_closure1.class
    11982  07-13-2020 04:23   grails/test/hibernate/HibernateSpec.class
     2392  07-13-2020 04:23   grails/test/hibernate/HibernateSpec$_setupSpec_closure2.class
     1733  07-13-2020 04:23   grails/test/hibernate/HibernateSpec$_canLoadFileExtension_closure5.class
     2392  07-13-2020 04:23   grails/test/hibernate/HibernateSpec$_setupSpec_closure4.class
        0  07-13-2020 04:23   org/
        0  07-13-2020 04:23   org/grails/
        0  07-13-2020 04:23   org/grails/plugin/
        0  07-13-2020 04:23   org/grails/plugin/hibernate/
        0  07-13-2020 04:23   org/grails/plugin/hibernate/support/
     8432  07-13-2020 04:23   org/grails/plugin/hibernate/support/HibernatePersistenceContextInterceptor.class
     1395  07-13-2020 04:23   org/grails/plugin/hibernate/support/AggregatePersistenceContextInterceptor.class
     3148  07-13-2020 04:23   org/grails/plugin/hibernate/support/GrailsOpenSessionInViewInterceptor.class
     4378  07-13-2020 04:23   org/grails/plugin/hibernate/support/AbstractMultipleDataSourceAggregatePersistenceContextInterceptor.class
      341  07-13-2020 04:23   org/grails/plugin/hibernate/support/SessionFactoryAwarePersistenceContextInterceptor.class
     1037  07-13-2020 04:23   META-INF/grails-plugin.xml
      145  07-13-2020 04:23   META-INF/grails.factories
---------                     -------
   112327                     41 files
% diff -r hibernate5-7.0.3 hibernate5-7.0.4
diff -r hibernate5-7.0.3/META-INF/grails-plugin.xml hibernate5-7.0.4/META-INF/grails-plugin.xml
1c1
< <plugin name='hibernate' version='7.0.3' grailsVersion='3.1.0 &gt; *'>
---
> <plugin name='hibernate' version='7.0.4' grailsVersion='3.1.0 &gt; *'>
diff -r hibernate5-7.0.3/META-INF/grails.factories hibernate5-7.0.4/META-INF/grails.factories
2c2
< #Fri Apr 03 17:10:38 UTC 2020
---
> #Mon Jul 13 04:23:52 UTC 2020
Binary files hibernate5-7.0.3/grails/orm/bootstrap/HibernateDatastoreSpringInitializer$_getBeanDefinitions_closure1$_closure2.class and hibernate5-7.0.4/grails/orm/bootstrap/HibernateDatastoreSpringInitializer$_getBeanDefinitions_closure1$_closure2.class differ

Only in hibernate5-7.0.4/grails/orm/bootstrap: HibernateDatastoreSpringInitializer$_getBeanDefinitions_closure1$_closure3$_closure5.class

Binary files hibernate5-7.0.3/grails/orm/bootstrap/HibernateDatastoreSpringInitializer$_getBeanDefinitions_closure1$_closure3.class and hibernate5-7.0.4/grails/orm/bootstrap/HibernateDatastoreSpringInitializer$_getBeanDefinitions_closure1$_closure3.class differ
Only in hibernate5-7.0.4/grails/orm/bootstrap: HibernateDatastoreSpringInitializer$_getBeanDefinitions_closure1$_closure4.class

Binary files hibernate5-7.0.3/grails/orm/bootstrap/HibernateDatastoreSpringInitializer$_getBeanDefinitions_closure1.class and hibernate5-7.0.4/grails/orm/bootstrap/HibernateDatastoreSpringInitializer$_getBeanDefinitions_closure1.class differ

Binary files hibernate5-7.0.3/grails/orm/bootstrap/HibernateDatastoreSpringInitializer.class and hibernate5-7.0.4/grails/orm/bootstrap/HibernateDatastoreSpringInitializer.class differ

Binary files hibernate5-7.0.3/grails/plugin/hibernate/Application.class and hibernate5-7.0.4/grails/plugin/hibernate/Application.class differ

Binary files hibernate5-7.0.3/grails/plugin/hibernate/HibernateGrailsPlugin$1.class and hibernate5-
7.0.4/grails/plugin/hibernate/HibernateGrailsPlugin$1.class differ

Binary files hibernate5-7.0.3/grails/plugin/hibernate/HibernateGrailsPlugin.class and hibernate5-7.0.4/grails/plugin/hibernate/HibernateGrailsPlugin.class differ

So the breaking changes would have to be in either HibernateDatastoreSpringInitializer.groovy, Application.groovy or HibernateGrailsPlugin.groovy

@puneetbehl puneetbehl transferred this issue from grails/grails-data-mapping Jul 24, 2021
@codeconsole
Copy link
Contributor Author

codeconsole commented Jul 24, 2021

Update:
I checked out this code. I built and used the 7.0.3 jar:

    implementation rootProject.files('lib/hibernate5-7.1.0.jar')
    implementation "org.grails:grails-datastore-gorm-hibernate5:7.0.5"

Verified WORKING

I built and used the 7.0.4 jar:

    implementation rootProject.files('lib/hibernate5-7.0.4.jar')
    implementation "org.grails:grails-datastore-gorm-hibernate5:7.0.5"

Verified NOT WORKING

I built a jar using the latest on the 7.0.x branch

    implementation rootProject.files('lib/hibernate5-7.0.6.jar')
    implementation "org.grails:grails-datastore-gorm-hibernate5:7.0.5"

Verified NOT WORKING

Using the latest 7.0.x branch, I made the following changes

index bf7d02c..0729ec1 100644
--- a/grails-plugin/src/main/groovy/grails/orm/bootstrap/HibernateDatastoreSpringInitializer.groovy
+++ b/grails-plugin/src/main/groovy/grails/orm/bootstrap/HibernateDatastoreSpringInitializer.groovy
@@ -17,6 +17,7 @@ package grails.orm.bootstrap
 import groovy.transform.CompileStatic
 import groovy.util.logging.Slf4j
 import org.grails.datastore.gorm.bootstrap.AbstractDatastoreInitializer
+import org.grails.datastore.gorm.bootstrap.support.ServiceRegistryFactoryBean
 import org.grails.datastore.gorm.jdbc.connections.CachedDataSourceConnectionSourceFactory
 import org.grails.datastore.gorm.support.AbstractDatastorePersistenceContextInterceptor
 import org.grails.datastore.mapping.config.DatastoreServiceMethodInvokingFactoryBean
@@ -161,20 +162,12 @@ class HibernateDatastoreSpringInitializer extends AbstractDatastoreInitializer {
                 bean.primary = true
             }
             autoTimestampEventListener(hibernateDatastore:"getAutoTimestampEventListener")
+            "hibernateDatastoreServiceRegistry"(ServiceRegistryFactoryBean, ref("hibernateDatastore"))
             getBeanDefinition("transactionManager").beanClass = PlatformTransactionManager
             hibernateDatastoreConnectionSourcesRegistrar(HibernateDatastoreConnectionSourcesRegistrar, dataSources)
             // domain model mapping context, used for configuration
             grailsDomainClassMappingContext(hibernateDatastore:"getMappingContext")
 
-            loadDataServices(null)
-                    .each {serviceName, serviceClass->
-                        "$serviceName"(DatastoreServiceMethodInvokingFactoryBean) {
-                            targetObject = ref("hibernateDatastore")
-                            targetMethod = 'getService'
-                            arguments = [serviceClass]
-                        }
-                    }
    implementation rootProject.files('lib/hibernate5-7.0.6-NEW.jar')
    implementation "org.grails:grails-datastore-gorm-hibernate5:7.0.5"

Verified WORKING

I then checked out master and applied those same changes to master

    implementation rootProject.files('lib/hibernate5-7.1.0.jar')
    implementation "org.grails:grails-datastore-gorm-hibernate5:7.1.0.RC1"

Therefore, the following code is 100% causing the issue:

-            loadDataServices(null)
-                    .each {serviceName, serviceClass->
-                        "$serviceName"(DatastoreServiceMethodInvokingFactoryBean) {
-                            targetObject = ref("hibernateDatastore")
-                            targetMethod = 'getService'
-                            arguments = [serviceClass]
-                        }
-                    }

Perhaps it is changing the loading of services which is overwriting the mime types that are available? I have no idea. All I know is it works when that code is reverted to

+            "hibernateDatastoreServiceRegistry"(ServiceRegistryFactoryBean, ref("hibernateDatastore"))

https://github.com/grails/gorm-hibernate5/compare/v7.0.3..v7.0.4

@codeconsole
Copy link
Contributor Author

Sample App that replicates

https://github.com/codeconsole/gormbug

@puneetbehl
Copy link
Contributor

@codeconsole Thank you for the great debugging effort, I will look into this soon.

@codeconsole
Copy link
Contributor Author

@puneetbehl I've updated the sample to 5.0.0.RC1 https://github.com/codeconsole/gormbug

@codeconsole
Copy link
Contributor Author

grails/grails-core#12057

@puneetbehl
Copy link
Contributor

@codeconsole Did you see this issue in Grails 4? if yes, could you please share a sample application? I am not able to replicate it with Grails 4.

@codeconsole
Copy link
Contributor Author

@puneetbehl It's not in Grails 4. Only Grails 5. It has nothing to do with that mentioned issue. Sorry for linking that to the ticket.

@puneetbehl
Copy link
Contributor

puneetbehl commented Oct 1, 2021

I think it might be related to the same underline issue. But, let me verify. Do you have a sample application for this?

@codeconsole
Copy link
Contributor Author

@puneetbehl I noticed it when I upgraded from Grails 4.x to Grails 5.x. Would you like me to create a 4.x sample app to verify?

@puneetbehl
Copy link
Contributor

Yes, please share a 4.0.x sample application.

@codeconsole
Copy link
Contributor Author

Grails 4.0.12 - Confirmed not working.
https://github.com/codeconsole/gormbug/tree/4.0.x

git clone https://github.com/codeconsole/gormbug
git checkout 4.0.x
./gradlew bootWar
java -jar build/libs/gormbug-1.6.8.war

@codeconsole
Copy link
Contributor Author

@puneetbehl I can confirm using 7.1.0-SNAPSHOT on 5.0.0.RC3 fixes the issue. Out of curiosity, why was it affecting the mime types?

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

No branches or pull requests

2 participants