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

Spring 3.2.2+ on GlassFish 3.1 leads to IllegalArgumentException: PWC2788: setAttribute: Non-serializable attribute [SPR-11389] #16016

Closed
spring-projects-issues opened this issue Feb 5, 2014 · 11 comments

Comments

@spring-projects-issues
Copy link
Collaborator

@spring-projects-issues spring-projects-issues commented Feb 5, 2014

Amit opened SPR-11389 and commented

While upgrading spring from 3.2.1 to 4.0.1, we replaced SpringBeanVariableResolver to SpringBeanFacesELResolver since it was removed

 <application>        
    <!--<variable-resolver>org.springframework.web.jsf.SpringBeanVariableResolver</variable-resolver>-->
    <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>

The application works as expected with spring 3.2.1 jars but setting an attribute in the session fails with the below error if we upgrade spring to 4.0.1

java.lang.IllegalArgumentException: PWC2788: setAttribute: Non-serializable attribute with name

I am using glassfish 3.1.2.2 (build 5)
Any inputs?


Affects: 3.2.2, 4.0.1

Reference URL: https://www.java.net/node/689993

Issue Links:

  • #14829 SpringServletContainerInitializer do annotation scan even if metadata-complete="true" in web.xml
  • #15794 web-application crashing when setting a non-serializable object into session
  • #14852 Tomcat Session Replication not working with Spring 3.2
@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Feb 5, 2014

Juergen Hoeller commented

Do you have stacktrace for this? Where exactly is this being raised, and what code on the application side triggers it?

Juergen

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Feb 5, 2014

Juergen Hoeller commented

This looks like it's caused by this change: #14852 - so the problem wouldn't be Spring 4 or SpringBeanFacesELResolver but rather Spring's web-fragment.xml in spring-web.jar...

GlassFish seems to be strict about web fragments marked with <distributable/>, which Spring's fragment declaration is since 3.2.2. We only mean to make the scenario 'distributable' very literally but GlassFish seems to interpret it as 'distributed' and insists on all session attributes to be serializable then.

So I suppose you're trying to set a non-serializable attribute to the session somewhere?

Juergen

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Feb 5, 2014

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Feb 5, 2014

Amit commented

Yes. I am trying to set a non-serializable attribute to the session.

The interesting part is that it works if spring libraries are places in glassfish\lib directory instead of placing it in the application's WEB-INF\lib directory.

Can you please share more details on what was the reason behind adding the <distributable> tag in the web-fragment.xml in spring 3.2.2?

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Feb 6, 2014

Juergen Hoeller commented

As raised in #14852, some servers - such as Tomcat and JBoss AS 7 - require all applicable web fragments to be marked as <distributable/> in order to allow for session replication. This is also in line with the naming of that attribute which implies that the particular code is designed to work in a distributed as well as a non-distributed environment.

So in order to generally allow for web application distribution, our web-fragment.xml had to be marked as <distributable/>. AFAIK, GlassFish is the only server which starts insisting on serializable session attributes because of that marker... instead of just insisting on serializable attributes in case of an actual session replication scenario.

Here's the corresponding GlassFish issue report: https://java.net/jira/browse/GLASSFISH-20917
The ZK framework ran into the same issue, still unresolved: http://tracker.zkoss.org/browse/ZK-2039

Aside from putting the Spring jars into a common directory (i.e. not WEB-INF/lib) to avoid detection of Spring's web-fragment, you could also declare your web.xml with <web-app ... metadata-complete="true"> to skip fragment scanning completely.

Juergen

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Feb 6, 2014

Juergen Hoeller commented

Also see the last comment on the related #14829: including an empty <absolute-ordering/> section in your web.xml might help as well, as an alternative to metadata-complete="true".

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Feb 6, 2014

Juergen Hoeller commented

FWIW, looking at the actual GlassFish code there, this is a simple assertion for java.io.Serializable and a few GlassFish-specific types, kicking in on setAttribute once a distributable marker has been found. That assertion is a bug in its own right; it shouldn't be there in that form at all but rather only apply if actual clustering is active.

So simply implementing Serializable in your attribute classes but not doing anything for actual serializability should work fine... since past that assertion, GlassFish would just store the attribute values regularly anyway if you're not actually using clustering.

I hope the above collection of workarounds helps. There's not much we can do here other than wait on a bug fix in GlassFish; and looking at GlassFish's state of affairs with hundreds of recent bugs still open in the issue tracker, that bug fix may take a while...

Juergen

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Feb 6, 2014

Juergen Hoeller commented

Also, notably, the Servlet 3.0 spec says the following about web fragment merging:

"The web.xml resulting from the merge is considered <distributable> only if all its web fragments are marked as <distributable> as well."

GlassFish clearly violates that rule, despite being the reference implementation.

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Feb 10, 2014

Amit commented

Thanks for the detailed replies. I understand that you propose 4 workarounds for this glassfish bug

  1. Moving the third party libraries to a central location
  2. Adding metadata-complete=true in web.xml. This doesn't seem to be an option because it would mean that the servlet container will not scan for servlet 3.0 annotations and web-fragment.xml's. We have some servlet 3.0 spec annotations being used in our application.
  3. Adding absolute-ordering. I understand that you meant adding an empty tag <absolute-ordering/> so that SpringServletContainerInitializer doesn't kick off. I didn't understand how could this could be a practical solution since adding an empty tag would mean no web-fragment.xml files will be scanned and that effectively means servlets, servlet-mappings, filters etc will not be loaded. Am I right?
  4. Implement Serializable and do nothing.

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Feb 10, 2014

Juergen Hoeller commented

With respect to absolute-ordering, that would indeed mean that only the primary web.xml is being respected. You could refer to specific additional fragments by name if you rely on well-known ones. Or you could use a patched version of the spring-web jar, simply deleting the web-fragment.xml there.

However, it looks like it's simpler to put the Spring jars into a server-level lib directory, not making them a target for web-fragment scanning to begin with.

Juergen

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Apr 13, 2016

test commented

I encountered the same issue. The workaround I used was to remove the <distributable/> mark from web-fragment.xml file in spring-web.jar :

$ jar xf spring-web-*.jar META-INF/web-fragment.xml
$ sed -i '/<distributable\/>/d' ./META-INF/web-fragment.xml
$ jar uf spring-web-*.jar META-INF/web-fragment.xml

Loading

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

Successfully merging a pull request may close this issue.

None yet
2 participants