Loading core/java/android/content/pm/PackageParser.java +67 −7 Original line number Diff line number Diff line Loading @@ -2745,15 +2745,15 @@ public class PackageParser { String cls = clsSeq.toString(); char c = cls.charAt(0); if (c == '.') { return (pkg + cls).intern(); return pkg + cls; } if (cls.indexOf('.') < 0) { StringBuilder b = new StringBuilder(pkg); b.append('.'); b.append(cls); return b.toString().intern(); return b.toString(); } return cls.intern(); return cls; } private static String buildCompoundName(String pkg, Loading @@ -2773,7 +2773,7 @@ public class PackageParser { + pkg + ": " + nameError; return null; } return (pkg + proc).intern(); return pkg + proc; } String nameError = validateName(proc, true, false); if (nameError != null && !"system".equals(proc)) { Loading @@ -2781,7 +2781,7 @@ public class PackageParser { + pkg + ": " + nameError; return null; } return proc.intern(); return proc; } private static String buildProcessName(String pkg, String defProc, Loading Loading @@ -5083,7 +5083,7 @@ public class PackageParser { if (v != null) { if (v.type == TypedValue.TYPE_STRING) { CharSequence cs = v.coerceToString(); data.putString(name, cs != null ? cs.toString().intern() : null); data.putString(name, cs != null ? cs.toString() : null); } else if (v.type == TypedValue.TYPE_INT_BOOLEAN) { data.putBoolean(name, v.data != 0); } else if (v.type >= TypedValue.TYPE_FIRST_INT Loading Loading @@ -5866,7 +5866,7 @@ public class PackageParser { // We use the boot classloader for all classes that we load. final ClassLoader boot = Object.class.getClassLoader(); packageName = dest.readString(); packageName = dest.readString().intern(); manifestPackageName = dest.readString(); splitNames = dest.readStringArray(); volumeUuid = dest.readString(); Loading @@ -5879,6 +5879,9 @@ public class PackageParser { splitPrivateFlags = dest.createIntArray(); baseHardwareAccelerated = (dest.readInt() == 1); applicationInfo = dest.readParcelable(boot); if (applicationInfo.permission != null) { applicationInfo.permission = applicationInfo.permission.intern(); } // We don't serialize the "owner" package and the application info object for each of // these components, in order to save space and to avoid circular dependencies while Loading @@ -5899,7 +5902,10 @@ public class PackageParser { fixupOwner(instrumentation); dest.readStringList(requestedPermissions); internStringArrayList(requestedPermissions); protectedBroadcasts = dest.createStringArrayList(); internStringArrayList(protectedBroadcasts); parentPackage = dest.readParcelable(boot); childPackages = new ArrayList<>(); Loading @@ -5909,16 +5915,23 @@ public class PackageParser { } staticSharedLibName = dest.readString(); if (staticSharedLibName != null) { staticSharedLibName = staticSharedLibName.intern(); } staticSharedLibVersion = dest.readInt(); libraryNames = dest.createStringArrayList(); internStringArrayList(libraryNames); usesLibraries = dest.createStringArrayList(); internStringArrayList(usesLibraries); usesOptionalLibraries = dest.createStringArrayList(); internStringArrayList(usesOptionalLibraries); usesLibraryFiles = dest.readStringArray(); final int libCount = dest.readInt(); if (libCount > 0) { usesStaticLibraries = new ArrayList<>(libCount); dest.readStringList(usesStaticLibraries); internStringArrayList(usesStaticLibraries); usesStaticLibrariesVersions = new int[libCount]; dest.readIntArray(usesStaticLibrariesVersions); usesStaticLibrariesCertDigests = new String[libCount]; Loading @@ -5937,7 +5950,13 @@ public class PackageParser { mAppMetaData = dest.readBundle(); mVersionCode = dest.readInt(); mVersionName = dest.readString(); if (mVersionName != null) { mVersionName = mVersionName.intern(); } mSharedUserId = dest.readString(); if (mSharedUserId != null) { mSharedUserId = mSharedUserId.intern(); } mSharedUserLabel = dest.readInt(); mSignatures = (Signature[]) dest.readParcelableArray(boot, Signature.class); Loading Loading @@ -5988,6 +6007,15 @@ public class PackageParser { restrictUpdateHash = dest.createByteArray(); } private static void internStringArrayList(List<String> list) { if (list != null) { final int N = list.size(); for (int i = 0; i < N; ++i) { list.set(i, list.get(i).intern()); } } } /** * Sets the package owner and the the {@code applicationInfo} for every component * owner by this package. Loading Loading @@ -6375,6 +6403,10 @@ public class PackageParser { super(in); final ClassLoader boot = Object.class.getClassLoader(); info = in.readParcelable(boot); if (info.group != null) { info.group = info.group.intern(); } tree = (in.readInt() == 1); group = in.readParcelable(boot); } Loading Loading @@ -6651,6 +6683,10 @@ public class PackageParser { for (ActivityIntentInfo aii : intents) { aii.activity = this; } if (info.permission != null) { info.permission = info.permission.intern(); } } public static final Parcelable.Creator CREATOR = new Parcelable.Creator<Activity>() { Loading Loading @@ -6735,6 +6771,10 @@ public class PackageParser { for (ServiceIntentInfo aii : intents) { aii.service = this; } if (info.permission != null) { info.permission = info.permission.intern(); } } public static final Parcelable.Creator CREATOR = new Parcelable.Creator<Service>() { Loading Loading @@ -6816,6 +6856,18 @@ public class PackageParser { for (ProviderIntentInfo aii : intents) { aii.provider = this; } if (info.readPermission != null) { info.readPermission = info.readPermission.intern(); } if (info.writePermission != null) { info.writePermission = info.writePermission.intern(); } if (info.authority != null) { info.authority = info.authority.intern(); } } public static final Parcelable.Creator CREATOR = new Parcelable.Creator<Provider>() { Loading Loading @@ -6888,6 +6940,14 @@ public class PackageParser { private Instrumentation(Parcel in) { super(in); info = in.readParcelable(Object.class.getClassLoader()); if (info.targetPackage != null) { info.targetPackage = info.targetPackage.intern(); } if (info.targetProcess != null) { info.targetProcess = info.targetProcess.intern(); } } public static final Parcelable.Creator CREATOR = new Parcelable.Creator<Instrumentation>() { Loading services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java +63 −25 Original line number Diff line number Diff line Loading @@ -140,6 +140,36 @@ public class PackageParserTest { assertAllFieldsExist(deserialized); } @Test public void test_stringInterning() throws Exception { PackageParser.Package pkg = new PackageParser.Package("foo"); setKnownFields(pkg); Parcel p = Parcel.obtain(); pkg.writeToParcel(p, 0 /* flags */); p.setDataPosition(0); PackageParser.Package deserialized = new PackageParser.Package(p); p.setDataPosition(0); PackageParser.Package deserialized2 = new PackageParser.Package(p); assertSame(deserialized.packageName, deserialized2.packageName); assertSame(deserialized.applicationInfo.permission, deserialized2.applicationInfo.permission); assertSame(deserialized.requestedPermissions.get(0), deserialized2.requestedPermissions.get(0)); assertSame(deserialized.protectedBroadcasts.get(0), deserialized2.protectedBroadcasts.get(0)); assertSame(deserialized.usesLibraries.get(0), deserialized2.usesLibraries.get(0)); assertSame(deserialized.usesOptionalLibraries.get(0), deserialized2.usesOptionalLibraries.get(0)); assertSame(deserialized.mVersionName, deserialized2.mVersionName); assertSame(deserialized.mSharedUserId, deserialized2.mSharedUserId); } /** * A trivial subclass of package parser that only caches the package name, and throws away * all other information. Loading Loading @@ -407,11 +437,11 @@ public class PackageParserTest { pkg.mTrustedOverlay = true; pkg.use32bitAbi = true; pkg.packageName = "foo"; pkg.splitNames = new String[] { "foo" }; pkg.volumeUuid = "foo"; pkg.codePath = "foo"; pkg.baseCodePath = "foo"; pkg.splitCodePaths = new String[] { "foo" }; pkg.splitNames = new String[] { "foo2" }; pkg.volumeUuid = "foo3"; pkg.codePath = "foo4"; pkg.baseCodePath = "foo5"; pkg.splitCodePaths = new String[] { "foo6" }; pkg.splitRevisionCodes = new int[] { 100 }; pkg.splitFlags = new int[] { 100 }; pkg.splitPrivateFlags = new int[] { 100 }; Loading @@ -428,48 +458,55 @@ public class PackageParserTest { pkg.providers.add(new PackageParser.Provider(dummy, new ProviderInfo())); pkg.services.add(new PackageParser.Service(dummy, new ServiceInfo())); pkg.instrumentation.add(new PackageParser.Instrumentation(dummy, new InstrumentationInfo())); pkg.requestedPermissions.add("foo"); pkg.requestedPermissions.add("foo7"); pkg.protectedBroadcasts = new ArrayList<>(); pkg.protectedBroadcasts.add("foo"); pkg.protectedBroadcasts.add("foo8"); pkg.parentPackage = new PackageParser.Package("foo"); pkg.parentPackage = new PackageParser.Package("foo9"); pkg.childPackages = new ArrayList<>(); pkg.childPackages.add(new PackageParser.Package("bar")); pkg.staticSharedLibName = "foo23"; pkg.staticSharedLibVersion = 100; pkg.usesStaticLibraries = new ArrayList<>(); pkg.usesStaticLibraries.add("foo23"); pkg.usesStaticLibrariesCertDigests = new String[] { "digest" }; pkg.usesStaticLibrariesVersions = new int[] { 100 }; pkg.libraryNames = new ArrayList<>(); pkg.libraryNames.add("foo"); pkg.libraryNames.add("foo10"); pkg.usesLibraries = new ArrayList<>(); pkg.usesLibraries.add("foo"); pkg.usesLibraries.add("foo11"); pkg.usesOptionalLibraries = new ArrayList<>(); pkg.usesOptionalLibraries.add("foo"); pkg.usesOptionalLibraries.add("foo12"); pkg.usesLibraryFiles = new String[] { "foo "}; pkg.usesLibraryFiles = new String[] { "foo13"}; pkg.mOriginalPackages = new ArrayList<>(); pkg.mOriginalPackages.add("foo"); pkg.mOriginalPackages.add("foo14"); pkg.mRealPackage = "foo"; pkg.mRealPackage = "foo15"; pkg.mAdoptPermissions = new ArrayList<>(); pkg.mAdoptPermissions.add("foo"); pkg.mAdoptPermissions.add("foo16"); pkg.mAppMetaData = new Bundle(); pkg.mVersionName = "foo"; pkg.mSharedUserId = "foo"; pkg.mVersionName = "foo17"; pkg.mSharedUserId = "foo18"; pkg.mSignatures = new Signature[] { new Signature(new byte[16]) }; pkg.mCertificates = new Certificate[][] { new Certificate[] { null }}; pkg.mExtras = new Bundle(); pkg.mRestrictedAccountType = "foo"; pkg.mRequiredAccountType = "foo"; pkg.mOverlayTarget = "foo"; pkg.mRestrictedAccountType = "foo19"; pkg.mRequiredAccountType = "foo20"; pkg.mOverlayTarget = "foo21"; pkg.mSigningKeys = new ArraySet<>(); pkg.mUpgradeKeySets = new ArraySet<>(); pkg.mKeySetMapping = new ArrayMap<>(); pkg.cpuAbiOverride = "foo"; pkg.cpuAbiOverride = "foo22"; pkg.restrictUpdateHash = new byte[16]; pkg.preferredActivityFilters = new ArrayList<>(); Loading Loading @@ -504,7 +541,7 @@ public class PackageParserTest { // Sanity check for list fields: Assume they're non-null and contain precisely // one element. List<?> list = (List<?>) f.get(pkg); assertNotNull(list); assertNotNull("List was null: " + f, list); assertEquals(1, list.size()); } else if (fieldType.getComponentType() != null) { // Sanity check for array fields: Assume they're non-null and contain precisely Loading @@ -514,15 +551,16 @@ public class PackageParserTest { } else if (fieldType == String.class) { // String fields: Check that they're set to "foo". String value = (String) f.get(pkg); assertEquals("foo", value); assertTrue("Bad value for field: " + f, value != null && value.startsWith("foo")); } else if (fieldType == int.class) { // int fields: Check that they're set to 100. int value = (int) f.get(pkg); assertEquals(100, value); assertEquals("Bad value for field: " + f, 100, value); } else { // All other fields: Check that they're set. Object o = f.get(pkg); assertNotNull("Field was null: " + f.getName(), o); assertNotNull("Field was null: " + f, o); } } } Loading Loading
core/java/android/content/pm/PackageParser.java +67 −7 Original line number Diff line number Diff line Loading @@ -2745,15 +2745,15 @@ public class PackageParser { String cls = clsSeq.toString(); char c = cls.charAt(0); if (c == '.') { return (pkg + cls).intern(); return pkg + cls; } if (cls.indexOf('.') < 0) { StringBuilder b = new StringBuilder(pkg); b.append('.'); b.append(cls); return b.toString().intern(); return b.toString(); } return cls.intern(); return cls; } private static String buildCompoundName(String pkg, Loading @@ -2773,7 +2773,7 @@ public class PackageParser { + pkg + ": " + nameError; return null; } return (pkg + proc).intern(); return pkg + proc; } String nameError = validateName(proc, true, false); if (nameError != null && !"system".equals(proc)) { Loading @@ -2781,7 +2781,7 @@ public class PackageParser { + pkg + ": " + nameError; return null; } return proc.intern(); return proc; } private static String buildProcessName(String pkg, String defProc, Loading Loading @@ -5083,7 +5083,7 @@ public class PackageParser { if (v != null) { if (v.type == TypedValue.TYPE_STRING) { CharSequence cs = v.coerceToString(); data.putString(name, cs != null ? cs.toString().intern() : null); data.putString(name, cs != null ? cs.toString() : null); } else if (v.type == TypedValue.TYPE_INT_BOOLEAN) { data.putBoolean(name, v.data != 0); } else if (v.type >= TypedValue.TYPE_FIRST_INT Loading Loading @@ -5866,7 +5866,7 @@ public class PackageParser { // We use the boot classloader for all classes that we load. final ClassLoader boot = Object.class.getClassLoader(); packageName = dest.readString(); packageName = dest.readString().intern(); manifestPackageName = dest.readString(); splitNames = dest.readStringArray(); volumeUuid = dest.readString(); Loading @@ -5879,6 +5879,9 @@ public class PackageParser { splitPrivateFlags = dest.createIntArray(); baseHardwareAccelerated = (dest.readInt() == 1); applicationInfo = dest.readParcelable(boot); if (applicationInfo.permission != null) { applicationInfo.permission = applicationInfo.permission.intern(); } // We don't serialize the "owner" package and the application info object for each of // these components, in order to save space and to avoid circular dependencies while Loading @@ -5899,7 +5902,10 @@ public class PackageParser { fixupOwner(instrumentation); dest.readStringList(requestedPermissions); internStringArrayList(requestedPermissions); protectedBroadcasts = dest.createStringArrayList(); internStringArrayList(protectedBroadcasts); parentPackage = dest.readParcelable(boot); childPackages = new ArrayList<>(); Loading @@ -5909,16 +5915,23 @@ public class PackageParser { } staticSharedLibName = dest.readString(); if (staticSharedLibName != null) { staticSharedLibName = staticSharedLibName.intern(); } staticSharedLibVersion = dest.readInt(); libraryNames = dest.createStringArrayList(); internStringArrayList(libraryNames); usesLibraries = dest.createStringArrayList(); internStringArrayList(usesLibraries); usesOptionalLibraries = dest.createStringArrayList(); internStringArrayList(usesOptionalLibraries); usesLibraryFiles = dest.readStringArray(); final int libCount = dest.readInt(); if (libCount > 0) { usesStaticLibraries = new ArrayList<>(libCount); dest.readStringList(usesStaticLibraries); internStringArrayList(usesStaticLibraries); usesStaticLibrariesVersions = new int[libCount]; dest.readIntArray(usesStaticLibrariesVersions); usesStaticLibrariesCertDigests = new String[libCount]; Loading @@ -5937,7 +5950,13 @@ public class PackageParser { mAppMetaData = dest.readBundle(); mVersionCode = dest.readInt(); mVersionName = dest.readString(); if (mVersionName != null) { mVersionName = mVersionName.intern(); } mSharedUserId = dest.readString(); if (mSharedUserId != null) { mSharedUserId = mSharedUserId.intern(); } mSharedUserLabel = dest.readInt(); mSignatures = (Signature[]) dest.readParcelableArray(boot, Signature.class); Loading Loading @@ -5988,6 +6007,15 @@ public class PackageParser { restrictUpdateHash = dest.createByteArray(); } private static void internStringArrayList(List<String> list) { if (list != null) { final int N = list.size(); for (int i = 0; i < N; ++i) { list.set(i, list.get(i).intern()); } } } /** * Sets the package owner and the the {@code applicationInfo} for every component * owner by this package. Loading Loading @@ -6375,6 +6403,10 @@ public class PackageParser { super(in); final ClassLoader boot = Object.class.getClassLoader(); info = in.readParcelable(boot); if (info.group != null) { info.group = info.group.intern(); } tree = (in.readInt() == 1); group = in.readParcelable(boot); } Loading Loading @@ -6651,6 +6683,10 @@ public class PackageParser { for (ActivityIntentInfo aii : intents) { aii.activity = this; } if (info.permission != null) { info.permission = info.permission.intern(); } } public static final Parcelable.Creator CREATOR = new Parcelable.Creator<Activity>() { Loading Loading @@ -6735,6 +6771,10 @@ public class PackageParser { for (ServiceIntentInfo aii : intents) { aii.service = this; } if (info.permission != null) { info.permission = info.permission.intern(); } } public static final Parcelable.Creator CREATOR = new Parcelable.Creator<Service>() { Loading Loading @@ -6816,6 +6856,18 @@ public class PackageParser { for (ProviderIntentInfo aii : intents) { aii.provider = this; } if (info.readPermission != null) { info.readPermission = info.readPermission.intern(); } if (info.writePermission != null) { info.writePermission = info.writePermission.intern(); } if (info.authority != null) { info.authority = info.authority.intern(); } } public static final Parcelable.Creator CREATOR = new Parcelable.Creator<Provider>() { Loading Loading @@ -6888,6 +6940,14 @@ public class PackageParser { private Instrumentation(Parcel in) { super(in); info = in.readParcelable(Object.class.getClassLoader()); if (info.targetPackage != null) { info.targetPackage = info.targetPackage.intern(); } if (info.targetProcess != null) { info.targetProcess = info.targetProcess.intern(); } } public static final Parcelable.Creator CREATOR = new Parcelable.Creator<Instrumentation>() { Loading
services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java +63 −25 Original line number Diff line number Diff line Loading @@ -140,6 +140,36 @@ public class PackageParserTest { assertAllFieldsExist(deserialized); } @Test public void test_stringInterning() throws Exception { PackageParser.Package pkg = new PackageParser.Package("foo"); setKnownFields(pkg); Parcel p = Parcel.obtain(); pkg.writeToParcel(p, 0 /* flags */); p.setDataPosition(0); PackageParser.Package deserialized = new PackageParser.Package(p); p.setDataPosition(0); PackageParser.Package deserialized2 = new PackageParser.Package(p); assertSame(deserialized.packageName, deserialized2.packageName); assertSame(deserialized.applicationInfo.permission, deserialized2.applicationInfo.permission); assertSame(deserialized.requestedPermissions.get(0), deserialized2.requestedPermissions.get(0)); assertSame(deserialized.protectedBroadcasts.get(0), deserialized2.protectedBroadcasts.get(0)); assertSame(deserialized.usesLibraries.get(0), deserialized2.usesLibraries.get(0)); assertSame(deserialized.usesOptionalLibraries.get(0), deserialized2.usesOptionalLibraries.get(0)); assertSame(deserialized.mVersionName, deserialized2.mVersionName); assertSame(deserialized.mSharedUserId, deserialized2.mSharedUserId); } /** * A trivial subclass of package parser that only caches the package name, and throws away * all other information. Loading Loading @@ -407,11 +437,11 @@ public class PackageParserTest { pkg.mTrustedOverlay = true; pkg.use32bitAbi = true; pkg.packageName = "foo"; pkg.splitNames = new String[] { "foo" }; pkg.volumeUuid = "foo"; pkg.codePath = "foo"; pkg.baseCodePath = "foo"; pkg.splitCodePaths = new String[] { "foo" }; pkg.splitNames = new String[] { "foo2" }; pkg.volumeUuid = "foo3"; pkg.codePath = "foo4"; pkg.baseCodePath = "foo5"; pkg.splitCodePaths = new String[] { "foo6" }; pkg.splitRevisionCodes = new int[] { 100 }; pkg.splitFlags = new int[] { 100 }; pkg.splitPrivateFlags = new int[] { 100 }; Loading @@ -428,48 +458,55 @@ public class PackageParserTest { pkg.providers.add(new PackageParser.Provider(dummy, new ProviderInfo())); pkg.services.add(new PackageParser.Service(dummy, new ServiceInfo())); pkg.instrumentation.add(new PackageParser.Instrumentation(dummy, new InstrumentationInfo())); pkg.requestedPermissions.add("foo"); pkg.requestedPermissions.add("foo7"); pkg.protectedBroadcasts = new ArrayList<>(); pkg.protectedBroadcasts.add("foo"); pkg.protectedBroadcasts.add("foo8"); pkg.parentPackage = new PackageParser.Package("foo"); pkg.parentPackage = new PackageParser.Package("foo9"); pkg.childPackages = new ArrayList<>(); pkg.childPackages.add(new PackageParser.Package("bar")); pkg.staticSharedLibName = "foo23"; pkg.staticSharedLibVersion = 100; pkg.usesStaticLibraries = new ArrayList<>(); pkg.usesStaticLibraries.add("foo23"); pkg.usesStaticLibrariesCertDigests = new String[] { "digest" }; pkg.usesStaticLibrariesVersions = new int[] { 100 }; pkg.libraryNames = new ArrayList<>(); pkg.libraryNames.add("foo"); pkg.libraryNames.add("foo10"); pkg.usesLibraries = new ArrayList<>(); pkg.usesLibraries.add("foo"); pkg.usesLibraries.add("foo11"); pkg.usesOptionalLibraries = new ArrayList<>(); pkg.usesOptionalLibraries.add("foo"); pkg.usesOptionalLibraries.add("foo12"); pkg.usesLibraryFiles = new String[] { "foo "}; pkg.usesLibraryFiles = new String[] { "foo13"}; pkg.mOriginalPackages = new ArrayList<>(); pkg.mOriginalPackages.add("foo"); pkg.mOriginalPackages.add("foo14"); pkg.mRealPackage = "foo"; pkg.mRealPackage = "foo15"; pkg.mAdoptPermissions = new ArrayList<>(); pkg.mAdoptPermissions.add("foo"); pkg.mAdoptPermissions.add("foo16"); pkg.mAppMetaData = new Bundle(); pkg.mVersionName = "foo"; pkg.mSharedUserId = "foo"; pkg.mVersionName = "foo17"; pkg.mSharedUserId = "foo18"; pkg.mSignatures = new Signature[] { new Signature(new byte[16]) }; pkg.mCertificates = new Certificate[][] { new Certificate[] { null }}; pkg.mExtras = new Bundle(); pkg.mRestrictedAccountType = "foo"; pkg.mRequiredAccountType = "foo"; pkg.mOverlayTarget = "foo"; pkg.mRestrictedAccountType = "foo19"; pkg.mRequiredAccountType = "foo20"; pkg.mOverlayTarget = "foo21"; pkg.mSigningKeys = new ArraySet<>(); pkg.mUpgradeKeySets = new ArraySet<>(); pkg.mKeySetMapping = new ArrayMap<>(); pkg.cpuAbiOverride = "foo"; pkg.cpuAbiOverride = "foo22"; pkg.restrictUpdateHash = new byte[16]; pkg.preferredActivityFilters = new ArrayList<>(); Loading Loading @@ -504,7 +541,7 @@ public class PackageParserTest { // Sanity check for list fields: Assume they're non-null and contain precisely // one element. List<?> list = (List<?>) f.get(pkg); assertNotNull(list); assertNotNull("List was null: " + f, list); assertEquals(1, list.size()); } else if (fieldType.getComponentType() != null) { // Sanity check for array fields: Assume they're non-null and contain precisely Loading @@ -514,15 +551,16 @@ public class PackageParserTest { } else if (fieldType == String.class) { // String fields: Check that they're set to "foo". String value = (String) f.get(pkg); assertEquals("foo", value); assertTrue("Bad value for field: " + f, value != null && value.startsWith("foo")); } else if (fieldType == int.class) { // int fields: Check that they're set to 100. int value = (int) f.get(pkg); assertEquals(100, value); assertEquals("Bad value for field: " + f, 100, value); } else { // All other fields: Check that they're set. Object o = f.get(pkg); assertNotNull("Field was null: " + f.getName(), o); assertNotNull("Field was null: " + f, o); } } } Loading