Skip to content

Commit d80bd1d

Browse files
ludochgae-java-bot
authored andcommitted
Delete the legacy App Engine Java SDK release directory.
PiperOrigin-RevId: 816874277 Change-Id: Ib5c5190caebdfd50f6828eaaddf33955a6f50c18
1 parent 4f38e38 commit d80bd1d

2 files changed

Lines changed: 248 additions & 0 deletions

File tree

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
/*
2+
* Copyright 2021 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.appengine.api.internal;
18+
19+
import static com.google.common.truth.Truth.assertThat;
20+
import static com.google.common.truth.Truth.assertWithMessage;
21+
import static org.junit.Assert.fail;
22+
23+
import com.google.appengine.api.ApiJarPath;
24+
import com.google.common.collect.ImmutableList;
25+
import com.google.common.collect.ImmutableSet;
26+
import com.google.common.reflect.ClassPath;
27+
import com.google.common.reflect.ClassPath.ClassInfo;
28+
import java.io.File;
29+
import java.io.IOException;
30+
import java.lang.reflect.Method;
31+
import java.net.URL;
32+
import java.net.URLClassLoader;
33+
import java.util.ArrayList;
34+
import java.util.Arrays;
35+
import java.util.Collection;
36+
import java.util.List;
37+
import java.util.regex.Pattern;
38+
import org.junit.Test;
39+
import org.junit.runner.RunWith;
40+
import org.junit.runners.JUnit4;
41+
42+
/**
43+
* Checks that instances of the repackaged {@code ImmutableList} class are recognized by {@link
44+
* Repackaged}, and that the other methods of {@code Repackaged} behave as expected.
45+
*/
46+
@RunWith(JUnit4.class)
47+
public class RepackagedTest {
48+
@Test
49+
public void recognizeRepackagedSdk() throws Exception {
50+
checkRecognized(ApiJarPath.getFile());
51+
}
52+
53+
@Test
54+
public void recognizeNotRepackaged() {
55+
List<List<String>> lists =
56+
Arrays.asList(
57+
ImmutableList.of(),
58+
ImmutableList.of("foo"),
59+
Arrays.asList("foo", "bar", "baz"),
60+
new ArrayList<>(Arrays.asList("buh", "blim")));
61+
for (List<String> list : lists) {
62+
assertThat(Repackaged.isRepackaged(list)).isFalse();
63+
assertThat(Repackaged.copyIfRepackagedElseOriginal(list)).isSameInstanceAs(list);
64+
}
65+
}
66+
67+
@Test
68+
public void notRepackagedUnmodifiable() {
69+
List<List<String>> lists =
70+
Arrays.asList(
71+
ImmutableList.of(),
72+
ImmutableList.of("foo"),
73+
Arrays.asList("foo", "bar", "baz"),
74+
new ArrayList<>(Arrays.asList("buh", "blim")));
75+
for (List<String> list : lists) {
76+
assertUnmodifiable(Repackaged.copyIfRepackagedElseUnmodifiable(list));
77+
}
78+
}
79+
80+
private static void checkRecognized(File apiJarFile)
81+
throws IOException, ReflectiveOperationException {
82+
assertWithMessage(apiJarFile.toString()).that(apiJarFile.exists()).isTrue();
83+
ClassLoader loader = new URLClassLoader(new URL[] {apiJarFile.toURI().toURL()}, null);
84+
ImmutableSet<ClassInfo> classInfos = ClassPath.from(loader).getAllClasses();
85+
List<ClassInfo> immutableListClasses = new ArrayList<>();
86+
for (ClassInfo classInfo : classInfos) {
87+
if (IMMUTABLE_LIST_PATTERN.matcher(classInfo.getName()).find()) {
88+
immutableListClasses.add(classInfo);
89+
}
90+
}
91+
assertThat(immutableListClasses).hasSize(1);
92+
Class<?> immutableListClass = immutableListClasses.get(0).load();
93+
assertThat(immutableListClass).isAssignableTo(List.class);
94+
check(immutableListClass, new Object[] {}, "of");
95+
check(immutableListClass, new Object[] {"foo"}, "of", Object.class);
96+
check(immutableListClass, new Object[] {Arrays.asList("foo")}, "copyOf", Collection.class);
97+
}
98+
99+
private static final Pattern IMMUTABLE_LIST_PATTERN = Pattern.compile("\\.\\$?ImmutableList$");
100+
101+
/**
102+
* Invokes the given static factory method from the repackaged {@code ImmutableList} class, via
103+
* reflection, to obtain a repackaged {@code ImmutableList} instance, then checks that {@link
104+
* Repackaged} identifies that instance as being of a repackaged class.
105+
*/
106+
private static void check(
107+
Class<?> immutableListClass,
108+
Object[] actualParams,
109+
String methodName,
110+
Class<?>... formalParams)
111+
throws ReflectiveOperationException {
112+
Method factory = immutableListClass.getMethod(methodName, formalParams);
113+
@SuppressWarnings("unchecked")
114+
List<String> list = (List<String>) factory.invoke(null, actualParams);
115+
assertThat(Repackaged.isRepackaged(list)).isTrue();
116+
117+
// Check that the copies have a null ClassLoader, meaning they're using a JRE core class,
118+
// and that they are unmodifiable.
119+
120+
List<String> copy1 = Repackaged.copyIfRepackagedElseOriginal(list);
121+
assertThat(copy1.getClass().getClassLoader()).isNull();
122+
assertUnmodifiable(copy1);
123+
124+
List<String> copy2 = Repackaged.copyIfRepackagedElseUnmodifiable(list);
125+
assertThat(copy2.getClass().getClassLoader()).isNull();
126+
assertUnmodifiable(copy2);
127+
}
128+
129+
private static void assertUnmodifiable(List<String> list) {
130+
try {
131+
list.add("foo");
132+
fail("List is modifiable");
133+
} catch (UnsupportedOperationException expected) {
134+
}
135+
}
136+
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/*
2+
* Copyright 2021 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.apphosting.runtime;
18+
19+
import static com.google.common.base.Preconditions.checkNotNull;
20+
import static com.google.common.base.Strings.lenientFormat;
21+
import static com.google.common.truth.Truth.assertWithMessage;
22+
23+
import com.google.appengine.api.ApiJarPath;
24+
import com.google.common.io.ByteSource;
25+
import com.google.common.primitives.Bytes;
26+
import java.io.ByteArrayOutputStream;
27+
import java.io.DataOutputStream;
28+
import java.io.FileNotFoundException;
29+
import java.io.IOException;
30+
import java.io.InputStream;
31+
import java.util.zip.ZipEntry;
32+
import java.util.zip.ZipFile;
33+
import org.junit.Test;
34+
import org.junit.runner.RunWith;
35+
import org.junit.runners.JUnit4;
36+
37+
/**
38+
* Test that verifies that appengine-api.jar includes expected implementation of JavaMail api.
39+
*
40+
* <p>We expect this implementation to be Geronimo JavaMail. Our heuristic is to check for expected
41+
* UTF-8 constants in javax/mail/internet/MimeMultipart.class.
42+
*/
43+
@RunWith(JUnit4.class)
44+
public final class CorrectMailApiTest {
45+
46+
public static final byte[] SESSION_UTIL_REF =
47+
utfBytes("org/apache/geronimo/mail/util/SessionUtil");
48+
public static final byte[] PROC_UTIL_REF = utfBytes("com/sun/mail/util/PropUtil");
49+
50+
public static final String MIME_MULTIPART = "javax/mail/internet/MimeMultipart.class";
51+
52+
@Test
53+
public void testContainsGeronimoMail() throws IOException {
54+
ZipFile zip = new ZipFile(ApiJarPath.getFile());
55+
ZipEntry mimeMultipartClass = zip.getEntry(MIME_MULTIPART);
56+
ByteSource byteSource = new ZipEntryByteSource(zip, mimeMultipartClass);
57+
byte[] classBytes = byteSource.read();
58+
// There should be a reference to SessionUtil from org/apache/geronimo
59+
assertWithMessage("Reference to org/apache/geronimo/mail/util/SessionUtil not found")
60+
.that(Bytes.indexOf(classBytes, SESSION_UTIL_REF))
61+
.isNotEqualTo(-1);
62+
// There should NOT be a reference to PropUtil from com/sun/mail.
63+
assertWithMessage("Unexpected reference to com/sun/mail/util/PropUtil found")
64+
.that(Bytes.indexOf(classBytes, PROC_UTIL_REF))
65+
.isEqualTo(-1);
66+
}
67+
68+
// Returns the UTF-8 encoding of `s`, including the length.
69+
private static byte[] utfBytes(String s) {
70+
try {
71+
return utfBytesOrException(s);
72+
} catch (IOException e) {
73+
throw new AssertionError(e);
74+
}
75+
}
76+
77+
private static byte[] utfBytesOrException(String s) throws IOException {
78+
ByteArrayOutputStream baos = new ByteArrayOutputStream();
79+
try (DataOutputStream dos = new DataOutputStream(baos)) {
80+
dos.writeUTF(s);
81+
}
82+
return baos.toByteArray();
83+
}
84+
85+
private static final class ZipEntryByteSource extends ByteSource {
86+
87+
private final ZipFile file;
88+
private final ZipEntry entry;
89+
90+
ZipEntryByteSource(ZipFile file, ZipEntry entry) {
91+
this.file = checkNotNull(file);
92+
this.entry = checkNotNull(entry);
93+
}
94+
95+
@Override
96+
public InputStream openStream() throws IOException {
97+
InputStream result = file.getInputStream(entry);
98+
if (result == null) {
99+
throw new FileNotFoundException(
100+
lenientFormat("entry %s not found in file %s", entry, file));
101+
}
102+
return result;
103+
}
104+
105+
// TODO: implement size() to try calling entry.getSize()?
106+
107+
@Override
108+
public String toString() {
109+
return "ZipFiles.asByteSource(" + file + ", " + entry + ")";
110+
}
111+
}
112+
}

0 commit comments

Comments
 (0)