You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by bu...@apache.org on 2004/04/07 19:07:03 UTC

DO NOT REPLY [Bug 28266] New: - after a file upload, the DynaActionForm is put into http session but is not serializable

DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG 
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://issues.apache.org/bugzilla/show_bug.cgi?id=28266>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND 
INSERTED IN THE BUG DATABASE.

http://issues.apache.org/bugzilla/show_bug.cgi?id=28266

after a file upload, the DynaActionForm is put into http session but is not serializable

           Summary: after a file upload, the DynaActionForm is put into http
                    session but is not serializable
           Product: Struts
           Version: 1.1 Final
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: Critical
          Priority: Other
         Component: File Upload
        AssignedTo: dev@struts.apache.org
        ReportedBy: quartz12h@yahoo.com


class=org.apache.struts.action.DynaActionForm
serialization: FAILED: java.io.NotSerializableException:
org.apache.struts.upload.CommonsMultipartRequestHandler$CommonsFormFile

I trap every session attribute with an http session listener.
The form is put into the session.

First of all, it is huge! Like 50k. The serialized data seams to contain beans,
props and a lot of unrelated crap. Somebody obviously forgot to put a field
transient.

Second of all, when the form is first put, beside that its size is big, it DOES
serializes, but if you try upload again, the form gets altered in some way and a
new field (org.apache.struts.upload.CommonsMultipartRequestHandler$CommonsFormFile)
get inserted and doesn't serializes.

The only way around is to remove the form from the session at the end of an
action, loosing all custom data.

WARN: HTTPSESSION ATTRIBUTE ADDED: 
	name=configUploadForm
	class=org.apache.struts.action.DynaActionForm
	serialization:
	########## Value takes unusualy large space (58088 bytes) ########## 
	ser.classes= (ignoring java.* and primitive types)
		org.apache.commons.beanutils.DynaProperty x 2
		org.apache.struts.action.ActionForm x 1
		org.apache.struts.action.ActionFormBean x 1
		org.apache.struts.action.ActionForward x 1
		org.apache.struts.action.ActionMapping x 1
		org.apache.struts.action.DynaActionForm x 1
		org.apache.struts.action.DynaActionFormClass x 1
		org.apache.struts.config.ActionConfig x 1
		org.apache.struts.config.ControllerConfig x 1
		org.apache.struts.config.ExceptionConfig x 1
		org.apache.struts.config.FormBeanConfig x 1
		org.apache.struts.config.FormPropertyConfig x 1
		org.apache.struts.config.ForwardConfig x 1
		org.apache.struts.config.MessageResourcesConfig x 1
		org.apache.struts.config.PlugInConfig x 1
		org.apache.struts.config.impl.ModuleConfigImpl x 1
		org.apache.struts.upload.FormFile x 1
	CONTENT:
		....sr.'org.apache.struts.action.DynaActionForm....*.#i...L..dyn
		aClasst..Lorg/apache/struts/action/DynaActionFormClass;L..dynaVa
		luest..Ljava/util/HashMap;xr.#org.apache.struts.action.ActionFor
		m.+.*v......xpsr.,org.apache.struts.action.DynaActionFormClass.f
		)y...A...L..configt.)Lorg/apache/struts/config/FormBeanConfig;L.
		.namet..Ljava/lang/String;[..propertiest.,[Lorg/apache/commons/b
		eanutils/DynaProperty;L..propertiesMapq.~..xpsr.'org.apache.stru
		ts.action.ActionFormBean..3........xr.'org.apache.struts.config.
		FormBeanConfig:&BV..U....Z..configuredZ..dynamicL..formPropertie
		sq.~..L..moduleConfigt.'Lorg/apache/struts/config/ModuleConfig;L
		..nameq.~..L..typeq.~..xp..sr..java.util.HashMap......`....F..lo
		adFactorI..thresholdxp?@......w.........t..configFilesr.+org.apa
		che.struts.config.FormPropertyConfig...k.h.....Z..configuredI..s
		izeL..initialq.~..L..nameq.~..L..typeq.~..xp.....pq.~..t.!org.ap
		ache.struts.upload.FormFilexsr..org.apache.struts.config.impl.Mo
		duleConfigImpl...;..h....Z..configuredL..actionConfigsq.~..L..ac
		tionMappingClassq.~..L..controllerConfigt.+Lorg/apache/struts/co
		nfig/ControllerConfig;L..dataSourcesq.~..L..exceptionsq.~..L..fo
		rmBeansq.~..L..forwardsq.~..L..messageResourcesq.~..L..plugInst.
		.Ljava/util/ArrayList;L..prefixq.~..xp.sq.~..?@......w.........t
		../admin/ntp/updatesr.&org.apache.struts.action.ActionMapping...
		..N.....xr.%org.apache.struts.config.ActionConfig...F..._...Z..c
		onfiguredZ..unknownZ..validateL..attributeq.~..L..exceptionsq.~.
                [many many pages, 50k]


Here is a utility inner classe for the listener, to trace classes:

	static boolean IGNORE_JAVA_AND_PRIMITIVE = true;
	
	static Set ignoresClasses = new HashSet();
	static {
		ignoresClasses.add("byte");
		ignoresClasses.add("short");
		ignoresClasses.add("char");
		ignoresClasses.add("int");
		ignoresClasses.add("long");
		ignoresClasses.add("float");
		ignoresClasses.add("double");
		ignoresClasses.add("boolean");
		ignoresClasses.add("java.lang.String");
	}
	



	public static class ClassLogObjectOutputStream extends ObjectOutputStream {
		Map classWrittenLog;
		int initdepth = -1;
		String indent;
		StringBuffer sb = new StringBuffer();
		
		ClassLogObjectOutputStream(OutputStream os, Map classWrittenLog) throws
IOException {
			this(os, classWrittenLog, "");
		}
		
		ClassLogObjectOutputStream(OutputStream os, Map classWrittenLog, String
indent) throws IOException {
			super(os);
			this.classWrittenLog = classWrittenLog;
			this.indent = indent;
		}
		
		protected void annotateClass(Class cl) throws IOException {
			recordUsage(cl);
			//StringBuffer sb = new StringBuffer();
			
			int depth = (new Throwable()).getStackTrace().length;
			if(initdepth<0)
				initdepth = depth;
			depth = (depth-initdepth);
			
			sb.append(indent).append(depth);
			//if(depth%2!=0)
			//	sb.append(".5");
			
			sb.append('\t');
			for(int i=0; i<depth; i++)
				sb.append('|').append(' ');//.append(' ');
			sb.append(cl.getName()).append('\n');
			//System.err.println(sb.toString());
			super.annotateClass(cl);
		}
		
		void recordUsage(Class cl) throws IOException {
			if(classWrittenLog!=null) {
				String name = buildName(cl);
				if(!IGNORE_JAVA_AND_PRIMITIVE || (!ignoresClasses.contains(name) &&
!name.startsWith("java.")) ) {
					int[] cnt = (int[])classWrittenLog.get(name);
					if(cnt==null) {
						cnt = new int[]{1};
						classWrittenLog.put(name, cnt);
					} else {
						cnt[0]++;
					}
				}
			}
		}
		
		String buildName(Class c) {
			if(c==null)
				return "<null class>";
			
			Class type = c;
			if(!c.isArray())
				return type.getName();
			
			type = c.getComponentType();
			return buildName(type);// + "[]";
		}
		
	}

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org