KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tctest > SerialVersionUIDTestApp


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
3  */

4 package com.tctest;
5
6 import org.apache.commons.io.IOUtils;
7
8 import com.tc.object.config.ConfigVisitor;
9 import com.tc.object.config.DSOClientConfigHelper;
10 import com.tc.object.config.TransparencyClassSpec;
11 import com.tc.process.LinkedJavaProcess;
12 import com.tc.process.StreamCollector;
13 import com.tc.simulator.app.ApplicationConfig;
14 import com.tc.simulator.listener.ListenerProvider;
15 import com.tc.util.Util;
16 import com.tctest.runner.AbstractTransparentApp;
17
18 import java.io.ByteArrayInputStream JavaDoc;
19 import java.io.ByteArrayOutputStream JavaDoc;
20 import java.io.FileInputStream JavaDoc;
21 import java.io.FileOutputStream JavaDoc;
22 import java.io.IOException JavaDoc;
23 import java.io.InputStream JavaDoc;
24 import java.io.ObjectInputStream JavaDoc;
25 import java.io.ObjectOutputStream JavaDoc;
26 import java.io.ObjectStreamClass JavaDoc;
27 import java.io.OutputStream JavaDoc;
28 import java.io.Serializable JavaDoc;
29 import java.lang.reflect.Field JavaDoc;
30 import java.lang.reflect.Modifier JavaDoc;
31 import java.util.Arrays JavaDoc;
32 import java.util.HashMap JavaDoc;
33 import java.util.Map JavaDoc;
34
35 public class SerialVersionUIDTestApp extends AbstractTransparentApp {
36
37   public static final String JavaDoc TEMP_FILE_KEY = "tempFile";
38
39   private final Map JavaDoc map = new HashMap JavaDoc();
40   private final String JavaDoc fileName;
41
42   public SerialVersionUIDTestApp(String JavaDoc appId, ApplicationConfig cfg, ListenerProvider listenerProvider) {
43     super(appId, cfg, listenerProvider);
44     this.fileName = cfg.getAttribute(TEMP_FILE_KEY);
45   }
46
47   public void run() {
48     final boolean first;
49     synchronized (map) {
50       first = map.isEmpty();
51       if (first) {
52         map.put("with", new WithUID());
53         map.put("without", new WithoutUID());
54       }
55     }
56
57     WithUID with = (WithUID) map.get("with");
58     WithoutUID without = (WithoutUID) map.get("without");
59
60     checkUID(with, WithUID.serialVersionUID);
61     checkUID(without, WithoutUID.EXPECTED_UID);
62
63     doTheDance(with);
64     doTheDance(without);
65
66     verifyAddedField(without);
67
68     if (first) {
69       // only do this in one node
70
verifyExternal();
71     }
72   }
73
74   private void verifyAddedField(WithoutUID without) {
75     Field JavaDoc field = getSerialUIDField(without);
76
77     if (field == null) { throw new RuntimeException JavaDoc("Could not find the serialVersionUID field: "
78                                                     + Arrays.asList(without.getClass().getDeclaredFields())); }
79
80     int access = field.getModifiers();
81     if ((!Modifier.isStatic(access)) || (!Modifier.isFinal(access))) {
82       // make formatter sane
83
throw new RuntimeException JavaDoc("Bad permissions: " + access);
84     }
85
86     Class JavaDoc type = field.getType();
87     if (!Long.TYPE.equals(type)) { throw new RuntimeException JavaDoc("Bad type: " + type); }
88
89     // a-okay, just return
90
return;
91   }
92
93   private void verifyExternal() {
94     // this verifies that we can share classes (via serialization) with a VM that doesn't use DSO instrumentation
95

96     byte[] dataIn = null;
97
98     try {
99       OutputStream JavaDoc out = new FileOutputStream JavaDoc(fileName + ".in", false);
100       out.write(serialize(new WithoutUID()));
101       out.close();
102
103       LinkedJavaProcess process = new LinkedJavaProcess(ExternalSerialize.class.getName(), new String JavaDoc[] { fileName });
104       process.start();
105
106       process.STDIN().close();
107       StreamCollector stdout = new StreamCollector(process.STDOUT());
108       stdout.start();
109       StreamCollector stderr = new StreamCollector(process.STDERR());
110       stderr.start();
111
112       int exitCode = process.waitFor();
113
114       stdout.join();
115       stderr.join();
116
117       if (exitCode != 0) { throw new RuntimeException JavaDoc("Process exited with code " + exitCode + ", stdout: "
118                                                       + stdout.toString() + ", stderr: " + stderr); }
119
120       InputStream JavaDoc in = new FileInputStream JavaDoc(fileName + ".out");
121       dataIn = IOUtils.toByteArray(in);
122       if (dataIn.length == 0) { throw new RuntimeException JavaDoc("No data read"); }
123       in.close();
124       deserialize(dataIn);
125     } catch (Exception JavaDoc e) {
126       throw new RuntimeException JavaDoc(Util.enumerateArray(dataIn), e);
127     }
128   }
129
130   private static Field JavaDoc getSerialUIDField(Object JavaDoc obj) {
131     Field JavaDoc[] fields = obj.getClass().getDeclaredFields();
132     for (int i = 0; i < fields.length; i++) {
133       Field JavaDoc f = fields[i];
134       if ("serialVersionUID".equals(f.getName())) { return f; }
135     }
136     return null;
137   }
138
139   private void doTheDance(Object JavaDoc obj) {
140     // this doesn't really test all that much, but it makes sure that the given object can be serialized and
141
// deserialized
142
try {
143       byte[] data = serialize(obj);
144       deserialize(data);
145     } catch (Exception JavaDoc e) {
146       notifyError(e);
147     }
148   }
149
150   private static Object JavaDoc deserialize(byte[] data) throws IOException JavaDoc, ClassNotFoundException JavaDoc {
151     ObjectInputStream JavaDoc ois = new ObjectInputStream JavaDoc(new ByteArrayInputStream JavaDoc(data));
152     Object JavaDoc rv = ois.readObject();
153     ois.close();
154     return rv;
155   }
156
157   private static byte[] serialize(Object JavaDoc obj) throws IOException JavaDoc {
158     ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc();
159     ObjectOutputStream JavaDoc oos = new ObjectOutputStream JavaDoc(baos);
160     oos.writeObject(obj);
161     oos.close();
162     return baos.toByteArray();
163   }
164
165   private void checkUID(Object JavaDoc obj, long expect) {
166     long uid = ObjectStreamClass.lookup(obj.getClass()).getSerialVersionUID();
167     if (uid != expect) { throw new RuntimeException JavaDoc("Unexpected UID: " + uid + ", expected " + expect); }
168   }
169
170   public static void visitL1DSOConfig(ConfigVisitor visitor, DSOClientConfigHelper config) {
171     String JavaDoc testClass = SerialVersionUIDTestApp.class.getName();
172     TransparencyClassSpec spec = config.getOrCreateSpec(testClass);
173     spec.addRoot("map", "map");
174
175     String JavaDoc methodExpression = "* " + testClass + ".*(..)";
176     config.addWriteAutolock(methodExpression);
177     
178     config.addIncludePattern(testClass + "$*");
179     
180     config.getOrCreateSpec(WithoutUID.class.getName());
181   }
182
183   private static class WithUID implements Serializable JavaDoc {
184     static final long serialVersionUID = 0xDECAFBAD;
185   }
186
187   public static class ExternalSerialize {
188
189     public static void main(String JavaDoc args[]) throws Exception JavaDoc {
190       try {
191         if (args.length != 1) {
192           error("invalid number of args " + args.length);
193         }
194
195         String JavaDoc file = args[0];
196
197         FileInputStream JavaDoc in = new FileInputStream JavaDoc(file + ".in");
198         byte[] dataIn = IOUtils.toByteArray(in);
199         in.close();
200
201         Object JavaDoc o = deserialize(dataIn);
202
203         verifyNoSerialUID(o);
204
205         FileOutputStream JavaDoc out = new FileOutputStream JavaDoc(file + ".out", false);
206         out.write(serialize(o));
207         out.flush();
208         out.close();
209         System.exit(0);
210       } catch (Throwable JavaDoc t) {
211         t.printStackTrace();
212         error(t.getMessage());
213       }
214
215     }
216
217     private static void verifyNoSerialUID(Object JavaDoc o) {
218       Field JavaDoc f = getSerialUIDField(o);
219       if (f != null) { throw new RuntimeException JavaDoc("Class has a serialVersionUID field: " + f); }
220     }
221
222     private static void error(String JavaDoc msg) {
223       System.err.println(msg);
224       System.err.flush();
225       System.exit(1);
226       throw new RuntimeException JavaDoc(msg);
227     }
228   }
229
230 }
231
Popular Tags