mirror of
https://github.com/google/nomulus.git
synced 2025-05-30 17:24:03 +02:00
Remove FieldExposers, since GAE reflection works normally
Calling setAccessible() cross-package used to fail in the custom security manager. It never shouldn have failed, and now it works correctly (not sure when it was fixed) so remove these trampolines. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=138549703
This commit is contained in:
parent
2cbfd6475d
commit
1abd0e1123
5 changed files with 6 additions and 193 deletions
|
@ -1,35 +0,0 @@
|
||||||
// Copyright 2016 The Nomulus Authors. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package google.registry.model;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A helper that exposes package-private fields in this package for reflective lookup.
|
|
||||||
*
|
|
||||||
* <p>By adding a subclass of this to every package in the model, we can write generic code that can
|
|
||||||
* access fields with package private access. The other alternative is to call
|
|
||||||
* {@link Field#setAccessible} with {@code true} on any such Field objects, but that does not work
|
|
||||||
* reliably in Google App Engine cross-package because of its custom security manager
|
|
||||||
* implementation.
|
|
||||||
*/
|
|
||||||
public abstract class AbstractFieldExposer {
|
|
||||||
public abstract Object getFieldValue(Object instance, Field field) throws IllegalAccessException;
|
|
||||||
|
|
||||||
public abstract void setFieldValue(Object instance, Field field, Object value)
|
|
||||||
throws IllegalAccessException;
|
|
||||||
|
|
||||||
public abstract void setAccessible(Field field);
|
|
||||||
}
|
|
|
@ -11,10 +11,7 @@ java_library(
|
||||||
"*.java",
|
"*.java",
|
||||||
"*/*.java",
|
"*/*.java",
|
||||||
"*/*/*.java",
|
"*/*/*.java",
|
||||||
]) + [
|
]),
|
||||||
"FieldExposerRegistry.java",
|
|
||||||
":field_exposers",
|
|
||||||
],
|
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
"//java/com/google/common/annotations",
|
"//java/com/google/common/annotations",
|
||||||
|
@ -42,57 +39,3 @@ java_library(
|
||||||
"//java/google/registry/xml",
|
"//java/google/registry/xml",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
# Generate FieldExposer classes to work around AppEngine's security limitations.
|
|
||||||
genrule(
|
|
||||||
name = "field_exposers",
|
|
||||||
srcs = ["generate_field_exposer.sh"],
|
|
||||||
outs = [
|
|
||||||
"FieldExposer.java",
|
|
||||||
"billing/FieldExposer.java",
|
|
||||||
"common/FieldExposer.java",
|
|
||||||
"contact/FieldExposer.java",
|
|
||||||
"dns/FieldExposer.java",
|
|
||||||
"domain/FieldExposer.java",
|
|
||||||
"domain/allocate/FieldExposer.java",
|
|
||||||
"domain/fee/FieldExposer.java",
|
|
||||||
"domain/fee06/FieldExposer.java",
|
|
||||||
"domain/fee11/FieldExposer.java",
|
|
||||||
"domain/fee12/FieldExposer.java",
|
|
||||||
"domain/flags/FieldExposer.java",
|
|
||||||
"domain/launch/FieldExposer.java",
|
|
||||||
"domain/rgp/FieldExposer.java",
|
|
||||||
"domain/secdns/FieldExposer.java",
|
|
||||||
"eppcommon/FieldExposer.java",
|
|
||||||
"eppinput/FieldExposer.java",
|
|
||||||
"eppoutput/FieldExposer.java",
|
|
||||||
"export/FieldExposer.java",
|
|
||||||
"host/FieldExposer.java",
|
|
||||||
"index/FieldExposer.java",
|
|
||||||
"mark/FieldExposer.java",
|
|
||||||
"ofy/FieldExposer.java",
|
|
||||||
"poll/FieldExposer.java",
|
|
||||||
"rde/FieldExposer.java",
|
|
||||||
"registrar/FieldExposer.java",
|
|
||||||
"registry/FieldExposer.java",
|
|
||||||
"registry/label/FieldExposer.java",
|
|
||||||
"reporting/FieldExposer.java",
|
|
||||||
"server/FieldExposer.java",
|
|
||||||
"smd/FieldExposer.java",
|
|
||||||
"tmch/FieldExposer.java",
|
|
||||||
"transfer/FieldExposer.java",
|
|
||||||
"translators/FieldExposer.java",
|
|
||||||
],
|
|
||||||
cmd = "for FILE in $(OUTS); do\n" +
|
|
||||||
" $(location generate_field_exposer.sh) $$FILE >> $$FILE\n" +
|
|
||||||
"done",
|
|
||||||
)
|
|
||||||
|
|
||||||
# Generate a registry of FieldExposers.
|
|
||||||
genrule(
|
|
||||||
name = "field_exposer_registry",
|
|
||||||
srcs = [":field_exposers"],
|
|
||||||
outs = ["FieldExposerRegistry.java"],
|
|
||||||
cmd = "$(location generate_field_exposer_registry.sh) $(SRCS) >$@",
|
|
||||||
tools = ["generate_field_exposer_registry.sh"],
|
|
||||||
)
|
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
|
|
||||||
package google.registry.model;
|
package google.registry.model;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
import static com.google.common.base.Predicates.instanceOf;
|
import static com.google.common.base.Predicates.instanceOf;
|
||||||
import static com.google.common.base.Predicates.isNull;
|
import static com.google.common.base.Predicates.isNull;
|
||||||
import static com.google.common.base.Predicates.or;
|
import static com.google.common.base.Predicates.or;
|
||||||
|
@ -27,7 +26,6 @@ import static java.util.Arrays.asList;
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
import com.google.common.base.Preconditions;
|
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.cache.CacheBuilder;
|
import com.google.common.cache.CacheBuilder;
|
||||||
import com.google.common.cache.CacheLoader;
|
import com.google.common.cache.CacheLoader;
|
||||||
|
@ -36,7 +34,6 @@ import com.google.common.collect.FluentIterable;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.ImmutableSortedMap;
|
import com.google.common.collect.ImmutableSortedMap;
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
import com.google.common.collect.Ordering;
|
import com.google.common.collect.Ordering;
|
||||||
import com.googlecode.objectify.Key;
|
import com.googlecode.objectify.Key;
|
||||||
import com.googlecode.objectify.annotation.Id;
|
import com.googlecode.objectify.annotation.Id;
|
||||||
|
@ -74,35 +71,17 @@ public class ModelUtils {
|
||||||
}
|
}
|
||||||
Map<String, Field> fields = new LinkedHashMap<>();
|
Map<String, Field> fields = new LinkedHashMap<>();
|
||||||
for (Class<?> hierarchyClass : hierarchy) {
|
for (Class<?> hierarchyClass : hierarchy) {
|
||||||
Package pakkage = hierarchyClass.getPackage();
|
|
||||||
// Don't use hierarchyClass.getFields() because it only picks up public fields.
|
// Don't use hierarchyClass.getFields() because it only picks up public fields.
|
||||||
for (Field field : hierarchyClass.getDeclaredFields()) {
|
for (Field field : hierarchyClass.getDeclaredFields()) {
|
||||||
if (Modifier.isStatic(field.getModifiers())) {
|
if (!Modifier.isStatic(field.getModifiers())) {
|
||||||
continue;
|
field.setAccessible(true);
|
||||||
|
fields.put(field.getName(), field);
|
||||||
}
|
}
|
||||||
// Strictly speaking this shouldn't be necessary since all of these fields
|
|
||||||
// are already accessible to their FieldExposer, but it is more performant
|
|
||||||
// to access fields if they are marked accessible this way because it skips
|
|
||||||
// various security checks.
|
|
||||||
checkNotNull(
|
|
||||||
FIELD_EXPOSERS.get(pakkage),
|
|
||||||
"No FieldExposer registered for %s", pakkage.getName())
|
|
||||||
.setAccessible(field);
|
|
||||||
fields.put(field.getName(), field);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ImmutableMap.copyOf(fields);
|
return ImmutableMap.copyOf(fields);
|
||||||
}});
|
}});
|
||||||
|
|
||||||
/** Per-package trampolines to expose package-private fields for reflection. */
|
|
||||||
private static final Map<Package, AbstractFieldExposer> FIELD_EXPOSERS = Maps.uniqueIndex(
|
|
||||||
FieldExposerRegistry.getFieldExposers(),
|
|
||||||
new Function<AbstractFieldExposer, Package>() {
|
|
||||||
@Override
|
|
||||||
public Package apply(AbstractFieldExposer exposer) {
|
|
||||||
return exposer.getClass().getPackage();
|
|
||||||
}});
|
|
||||||
|
|
||||||
/** Lists all instance fields on an object, including non-public and inherited fields. */
|
/** Lists all instance fields on an object, including non-public and inherited fields. */
|
||||||
static Map<String, Field> getAllFields(Class<?> clazz) {
|
static Map<String, Field> getAllFields(Class<?> clazz) {
|
||||||
return ALL_FIELDS_CACHE.getUnchecked(clazz);
|
return ALL_FIELDS_CACHE.getUnchecked(clazz);
|
||||||
|
@ -187,10 +166,7 @@ public class ModelUtils {
|
||||||
/** Retrieves a field value via reflection. */
|
/** Retrieves a field value via reflection. */
|
||||||
static Object getFieldValue(Object instance, Field field) {
|
static Object getFieldValue(Object instance, Field field) {
|
||||||
try {
|
try {
|
||||||
return Preconditions.checkNotNull(
|
return field.get(instance);
|
||||||
FIELD_EXPOSERS.get(field.getDeclaringClass().getPackage()),
|
|
||||||
"No FieldExposer registered for %s", field.getDeclaringClass().getPackage().getName())
|
|
||||||
.getFieldValue(instance, field);
|
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
throw new IllegalStateException(e);
|
throw new IllegalStateException(e);
|
||||||
}
|
}
|
||||||
|
@ -199,10 +175,7 @@ public class ModelUtils {
|
||||||
/** Sets a field value via reflection. */
|
/** Sets a field value via reflection. */
|
||||||
static void setFieldValue(Object instance, Field field, Object value) {
|
static void setFieldValue(Object instance, Field field, Object value) {
|
||||||
try {
|
try {
|
||||||
Preconditions.checkNotNull(
|
field.set(instance, value);
|
||||||
FIELD_EXPOSERS.get(field.getDeclaringClass().getPackage()),
|
|
||||||
"No FieldExposer registered for %s", field.getDeclaringClass().getPackage().getName())
|
|
||||||
.setFieldValue(instance, field, value);
|
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
throw new IllegalStateException(e);
|
throw new IllegalStateException(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
#!/bin/sh -
|
|
||||||
# Copyright 2016 The Nomulus Authors. All Rights Reserved.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
|
|
||||||
# Generate a FieldExposer for a given package
|
|
||||||
|
|
||||||
printf "package google.registry.model"\
|
|
||||||
`echo $1 | sed -e 's/.*\/model\(.*\).FieldExposer\.java/\1/' -e 's/\//./g'`";\
|
|
||||||
\n\n\
|
|
||||||
import google.registry.model.AbstractFieldExposer;\n\n\
|
|
||||||
import java.lang.reflect.Field;\n\n\
|
|
||||||
/** A helper that exposes package-private fields in this package for reflective lookup. */\n\
|
|
||||||
public class FieldExposer extends AbstractFieldExposer {\n\
|
|
||||||
public Object getFieldValue(Object instance, Field field) throws IllegalAccessException {\n\
|
|
||||||
return field.get(instance);\n\
|
|
||||||
}\n\n\
|
|
||||||
public void setFieldValue(Object instance, Field field, Object value)\n\
|
|
||||||
throws IllegalAccessException {\n\
|
|
||||||
field.set(instance, value);\n\
|
|
||||||
}\n\n\
|
|
||||||
public void setAccessible(Field field) {\n\
|
|
||||||
field.setAccessible(true);\n\
|
|
||||||
}\n\
|
|
||||||
}\n"
|
|
|
@ -1,32 +0,0 @@
|
||||||
#!/bin/sh -
|
|
||||||
# Copyright 2016 The Nomulus Authors. All Rights Reserved.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
|
|
||||||
# Generate a FieldExposer for a given package
|
|
||||||
|
|
||||||
printf "package google.registry.model;\n\n\
|
|
||||||
import google.registry.model.AbstractFieldExposer;\n\n\
|
|
||||||
import com.google.common.collect.ImmutableList;\n\n\
|
|
||||||
/** A registry of all {@link AbstractFieldExposer} impls. */\n\
|
|
||||||
class FieldExposerRegistry {\n\
|
|
||||||
static ImmutableList<AbstractFieldExposer> getFieldExposers() {\n\
|
|
||||||
return new ImmutableList.Builder<AbstractFieldExposer>()\n"
|
|
||||||
for FILE in $@; do
|
|
||||||
echo $FILE | sed \
|
|
||||||
-e 's!^.*/java/\(.*\)\.java$! .add(new \1())!' \
|
|
||||||
-e 's!/!.!g'
|
|
||||||
done
|
|
||||||
printf " .build();\n"
|
|
||||||
printf " }\n}\n"
|
|
Loading…
Add table
Add a link
Reference in a new issue