From james.laskey at oracle.com Thu Jul 5 20:11:43 2018 From: james.laskey at oracle.com (Jim Laskey) Date: Thu, 5 Jul 2018 17:11:43 -0300 Subject: Targeting JEP 326: Raw String Literal for JDK 12 Message-ID: <0B907300-0238-4D6C-A559-AF8BB4E20E27@oracle.com> With your guidance, we consider the Raw String Literal design and initial implementation has stabilized enough to target JEP 326 as a Preview Language Feature in JDK 12. Before we proceed, we?d like review some of recommendations made since JEP 326 was proposed as Candidate. Margin Management Considerable time was spent discussing how to deal with incidental indentation introduced when a Raw String Literal?s visible content marshals with surrounding code. Clearly, there is no all satisfying solution. We would be remiss if we were to lock the language into a irreversible decision that we may regret in the future. Therefore, the sensible/responsible thing to do is to follow the "raw means raw" principle and leave the Raw String Literal content uninterpreted (other than line terminators) by the compiler, and place the margin management onus on library and developer furnished methods. To provide incidental indentation support for what we think will be the common case, the following instance method will be added to the String class: public String align() which after removing all leading and trailing blank lines, left justifies each line without loss of relative indentation. Thus, stripping away all incidental indentation and line spacing. Example: String html = `

Hello World.

`.align(); System.out.print(html); Output:

Hello World.&

Further, generalized control of indentation will be provided with the following String instance method: public String indent(int n) where `n` specifies the number of white spaces to add or remove from each line of the string; a positive `n` adds n spaces (U+0020) and negative `n` removes n white spaces. Example: String html = `

Hello World.

`.align().indent(4); System.out.print(html); Output:

Hello World.&

In the cases where align() is not what the developer wants, we expect the preponderance of cases to be align().ident(n). Therefore, an additional variation of `align` will be provided: public align(int n) where `n` is the indentation applied to the string after _alignment_. Example: String html = `

Hello World.

`.align(4); System.out.print(html); Output:

Hello World.&

Customizable margin management (and more) will be provided by the string instance method: R transform?(Function f) where the supplied function f is called with the string. Example: public class MyClass { private static final String MARGIN_MARKER= "| "; public String stripMargin(String string) { return lines().map(String::strip) .map(s -> s.startsWith(MARGIN_MARKER) ? s.substring(MARGIN_MARKER.length()) : s) .collect(Collectors.joining("\n", "", "\n")); } String stripped = ` | The content of | the string `.transform(MyClass::stripMargin); Output: The content of the string It should be noted that concern for class file size and runtime impact are addressed by the _constant folding_ features of [JEP 303](http://openjdk.java.net/jeps/303 ). White Space and Tabs The use of tabs came up during the Margin Management discussion. Specifically, what do tabs represent when removing incidental indentation. As long as the source was consistent across all lines of a multi-line string (with respect to tabs), the align() method will behave as expected. For the cases where it does not, there is no consistent rule for handling it; the best thing to do here is to provide tools for getting back to consistency. For example, we propose the introduction of String instance method: public String detab(int n) which replaces tab U+0009 characters with enough space U+0020 characters to align to tab stops at intervals n, and: public String entab(int n) which replaces some space U+0020 characters with tab U+0009 characters if can align to tab stops at intervals n. Example: String html = `

Hello World.

`.detab(8).align(4); System.out.print(html); Output:

Hello World.&

Escape Sequences After the initial release of JEP 326 there was some discussion about the names of the escape sequence managing methods. We reversed the naming (unescape/escape), but the lack of additional feedback left us wondering, ?Do we have the appropriate names?? and ?Do we really need these methods?? If these methods are needed rarely, would longer names escapeSequencesToChars and charsToEscapeSequences be more suitable? Would more putting effort into a more generalized String::replaceAll(Pattern pattern, Function replacer)) make more sense? Repeating Delimiters We remain convinced that the choice of an arbitrary sequence of backticks as a delimiter is the best choice. There were two main points of concern; the lack of empty string and the distinction between single & multi-line literals. We contend both of these points are aesthetic and if were part of the design, would take away from the simplicity. With regards to empty Raw String Literal. Java already has a representation for empty string; ??. Why have two? Raw String Literals do not have to be symmetrically in sync with traditional strings. The lack of symmetry is a discerning plus for Raw String Literal. With regards to distinction between single & multi-line literals. If the developer chooses to use single backticks for single line and triple backticks for multi-line there is nothing in the design that prevents the developer from doing so. However, we would discourage the adoption of this "coding convention". Cheers, - Jim From guy.steele at oracle.com Thu Jul 5 20:37:35 2018 From: guy.steele at oracle.com (Guy Steele) Date: Thu, 5 Jul 2018 16:37:35 -0400 Subject: Targeting JEP 326: Raw String Literal for JDK 12 In-Reply-To: <0B907300-0238-4D6C-A559-AF8BB4E20E27@oracle.com> References: <0B907300-0238-4D6C-A559-AF8BB4E20E27@oracle.com> Message-ID: > On Jul 5, 2018, at 4:11 PM, Jim Laskey wrote: > > With your guidance, we consider the Raw String Literal design and initial implementation has stabilized enough to target JEP 326 as a Preview Language Feature in JDK 12. Before we proceed, we?d like review some of recommendations made since JEP 326 was proposed as Candidate. > . . . A warning: not all of the given ?Output? examples have exactly the correct number of leading spaces on all lines. In the example for ?align()?, for example, what is shown is: Example: String html = `

Hello World.

`.align(); System.out.print(html); Output:

Hello World.&

but I believe the correct output would be: Output:

Hello World.&

That is, each of the middle three lines of output needed to have an additional leading space character. Otherwise everything in the email looked okay to me. ?Gy From james.laskey at oracle.com Thu Jul 5 21:05:51 2018 From: james.laskey at oracle.com (James Laskey) Date: Thu, 5 Jul 2018 18:05:51 -0300 Subject: Targeting JEP 326: Raw String Literal for JDK 12 In-Reply-To: References: <0B907300-0238-4D6C-A559-AF8BB4E20E27@oracle.com> Message-ID: <00737357-8E9F-4CA7-B69D-8A321D8E373C@oracle.com> You are correct. I thought I caught all the stray cases, but... The examples should have indentations that are multiples of 4. The issue with pasting from IDEs to mailers. Sent from my iPhone > On Jul 5, 2018, at 5:37 PM, Guy Steele wrote: > > >> On Jul 5, 2018, at 4:11 PM, Jim Laskey wrote: >> >> With your guidance, we consider the Raw String Literal design and initial implementation has stabilized enough to target JEP 326 as a Preview Language Feature in JDK 12. Before we proceed, we?d like review some of recommendations made since JEP 326 was proposed as Candidate. >> . . . > > > A warning: not all of the given ?Output? examples have exactly the correct number of leading spaces on all lines. In the example for ?align()?, for example, what is shown is: > > Example: > > String html = ` > > >

Hello World.

> > > `.align(); > System.out.print(html); > > Output: > > >

Hello World.&

> > > > but I believe the correct output would be: > > Output: > > >

Hello World.&

> > > > That is, each of the middle three lines of output needed to have an additional leading space character. > > Otherwise everything in the email looked okay to me. > > ?Gy > > > From daniel.smith at oracle.com Fri Jul 6 22:26:39 2018 From: daniel.smith at oracle.com (Dan Smith) Date: Fri, 6 Jul 2018 16:26:39 -0600 Subject: [RSL] RSL update In-Reply-To: <059fe719-1374-a013-571a-7b4a357012e9@oracle.com> References: <059fe719-1374-a013-571a-7b4a357012e9@oracle.com> Message-ID: > On Jun 26, 2018, at 6:09 AM, Brian Goetz wrote: > > >> Here are two more arguments in favor of language-level stripping: >> >> 1. Strings inside annotations aren't left out. Whenever an annotation attribute feels like something users may want to use an RSL for, the best we can hope for (if we don't have automatic unindenting) is for the specification of that attribute to say "consumers of this data really should call .align() on this" - quite unsatisfying, and we can be sure most annotation specs won't bother. > > This seems like a pretty corner^3 case to me; long strings in annotations are kind of questionable already, multi-line strings in an annotation seem even more so, and in those cases where you absolutely need to be divorced from the incidental indentation, you could just align it yourself correctly, at the cost of uglier indentation (or pull it out into a static var.) Just to be clear about dependencies: "pull it out into a static var" only works if the 'align' call is a constant expression. Which it ought to be, yes, but that's a separate feature we'll need to deliver. (And really ought to, I think. Otherwise, if we anticipate some releases in which 'align' calls disrupt what would otherwise be constant expressions, that's a notable argument in favor of the language approach.) From forax at univ-mlv.fr Mon Jul 9 06:39:42 2018 From: forax at univ-mlv.fr (Remi Forax) Date: Mon, 9 Jul 2018 08:39:42 +0200 (CEST) Subject: Extending 15.28 to include toString() on an enum constant Message-ID: <73648976.40631.1531118382273.JavaMail.zimbra@u-pem.fr> [this was sent to the amber-spec-comment] Hi Daniel, ----- Mail original ----- > De: "Daniel Trebbien" > ?: "amber-spec-comments" > Envoy?: Lundi 9 Juillet 2018 02:43:00 > Objet: Extending 15.28 to include toString() on an enum constant > One small idea I have for enhancing the Java language is to allow > toString() on enum constants to be used in constant expressions, as long as > toString() > > is not overidden, or if it is, the implementation returns a constant > expression. > > There are two use cases I have in mind for this: > > 1. When using the SLF4J logging library, if you want to embed the name of > an enum constant in the log message, you should use parameterized logging > to avoid incurring a wasted runtime string concatenation if logging at the > specified level is disabled. See SLF4J's FAQ for "What is the fastest way > of (not) logging?": https://www.slf4j.org/faq.html#logging_performance > As an example of this in the wild, I submitted a pull request in which I > converted a log statement involving an enum constant to parameterized > logging: > https://github.com/Netflix/eureka/commit/ad81a1140f351ec19165cb94d5aa668cfc08a932 > There are other cases where an SLF4J logger call involving an enum constant > correctly used parameterized logging, but I am not able to find an example > right now. SLF4J should offer to have a lambda as parameter (as log4j2 does), parameterized logging solve the problem of the cost when not logging but at the cost of slowing down the logging when the logger logs because it has to do string interpolation. > > Although using parameterized logging solves the performance issue, it is > desirable to keep down the number of parameters to an SLF4J logger call > because the SLF4J Logger interface > has more efficient > variants of the trace(), debug(), info(), warn(), and error() calls that > take zero, exactly one, and exactly two parameters. If a logger call > passes at most two parameters, then the construction of an Object array to > package the parameters into varargs is avoided. Needing to "waste" a > parameter slot on an enum constant is undesirable. > > 2. When using Spring Security, it is possible to define an enum that lists > the roles and other categories of permissions that are used by a Spring > application. For example: > > package com.myapp.security; > > import org.springframework.security.core.GrantedAuthority; > > public enum AppAuthority implements GrantedAuthority { > > ROLE_USER, > ROLE_ADMINISTRATOR; > > @Override > public String getAuthority() { > return toString(); > } > } > > When using the org.springframework.security.access.annotation.Secured > > annotation to secure controllers or actions, it would be nice to be able to > use an enum constant in the annotation's value, as in @Secured({ > ROLE_ADMINISTRATOR.toString() }); however, this is currently not valid Java > code because ROLE_ADMINISTRATOR.toString() is not a constant expression. > Instead, the name of the role must be duplicated: @Secured({ " > ROLE_ADMINISTRATER" }). This is undesirable because it is error-prone and > makes refactoring more difficult. It is also more difficult to find usages > of a particular authority. If toString() on an enum constant were allowed > within a constant expression, then finding usages of a particular authority > would be a "Find Usages" operation in an IDE. JEP 303 (http://openjdk.java.net/jeps/303) allows to build such kind of constants, i don't know if it works in the context of annotations but it's a nice use case. The other solution is to allow any expressions in a annotation context and let the compiler emit a Constant_Dynamic that will be initialized with that expression, this solution has the advantage over the JEP 303 of not evaluating the expression by the compiler but at runtime by the VM, meaning that if there is a bug in toString() or in any calls inside of the expression, you do not have to re-compile the code. As a war story, a friend of mine has exactly the same issue with a Kotlin function which checks some credential and is marked inline there was a bug in it, so he rolls a security fix only to see that the bug was still appearing sometimes because he had to recompile all the codes that were using that function too. regards, R?mi From maurizio.cimadamore at oracle.com Mon Jul 9 08:52:11 2018 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Mon, 9 Jul 2018 09:52:11 +0100 Subject: Extending 15.28 to include toString() on an enum constant In-Reply-To: <73648976.40631.1531118382273.JavaMail.zimbra@u-pem.fr> References: <73648976.40631.1531118382273.JavaMail.zimbra@u-pem.fr> Message-ID: Remi is correct - 303 has the potential to special case toString() method calls on enums. One thing that 303 lacks, at least at the moment, is the ability to redefine what goes into places where a constant expression is expected (case labels, annotations, ...). That is, the additional constant propagation occurs *after* type-checking, and it's mostly there to support code generation. What you ask would have an impact on the language frontend (and would therefore require some spec text for it) - I'm unsure as to whether this falls within the scope of 303. Maurizio On 09/07/18 07:39, Remi Forax wrote: > JEP 303 (http://openjdk.java.net/jeps/303) allows to build such kind of constants, i don't know if it works in the context of annotations but it's a nice use case. From brian.goetz at oracle.com Mon Jul 9 12:55:39 2018 From: brian.goetz at oracle.com (Brian Goetz) Date: Mon, 9 Jul 2018 08:55:39 -0400 Subject: Fwd: Extending 15.28 to include toString() on an enum constant In-Reply-To: References: Message-ID: <57aa3237-3466-df7e-2603-5528e0bba21f@oracle.com> The following was received on the -comments list. Here's my thoughts on this. This is a prime example of the sort of language feature that could be described as "opening a fresh can of worms."? In addition to increasing the complexity of the language by adding a narrow and esoteric irregularity (special treatment for toString()), it would surely be the case that tomorrow, there would be a long line of similar irregularities queueing up to demand equal treatment. But, the problems you cite are real concerns, so let's talk about those, rather than the specific solution.? The first observes how non-logging of constants is less expensive than non-logging of non-constants.? As an example, you cite this change: -??????????? logger.info("Datacenter is: " + DataCenterInfo.Name.Amazon); +??????????? logger.info("Datacenter is: {}", DataCenterInfo.Name.Amazon); There are other common ways to handle this in logging frameworks. One is to pass a lambda instead of arguments; another is to unroll the constant yourself: +??????????? logger.info("Datacenter is: AMAZON"); Logging is a bit of a special case, since in few other APIs do you regularly pass expressions that most of the time you wish would not actually be evaluated.? And I would suggest that this sort of almost-but-not-quite-foldable string concatenation is a relatively rare case.? So I'm not really seeing this as a big motivation for an irregular change. That said, there are some other operations that are far more deserving of better compile-time treatment.? In the context of raw string literals, we expect the `align()` call to be common; given that `align()` is pure, evaluating it at compile time rather than run time will be a big win.? You should expect to see this sort of thing coming out of JEP 303.? (Though I doubt it would go as far as `toString()` on enums, because at compile time, we cannot prove that _at run time_ `toString()` would not have been overridden.? Constant-folding of static methods is far less problematic than for virtual methods.) You raised a second case: constants in annotations.? This is very different in character from the first case.? The first case is a pure quest-for-performance; hoping that the compile/runtime can optimize something better.? The second is looking for language changes to make annotations more expressive; extending the notion of "constant expression" so more expressions can be used as annotation parameters.? We've actually thought about this quite a bit in the context of JEP 303. My conclusion is: this would be a bad idea.? It's great if the compiler can opportunistically spot opportunities to eliminate computation, but tying the semantics of a high-level language construct to this is pretty dangerous.? It means that in order to correctly reason about what can go in an annotation, every developer must be able to correctly reason about all the optimizations a compiler might do -- which is clearly a recipe for frustration and confusion. Additionally, I thing the resulting language is not one we'll want to program in.? When you pull this string to the end, you will end up with complex mini-programs as parameters to annotations.? But annotations are for metadata, not carriers for mini-programs. (We also confronted this from another angle; it has recently become practical to allow putting (non-bound) method references in annotations, which is a reasonable fit for the role of annotations.? But the obvious next question is: what about lambdas?? And while the machinery is the same, this is almost certainly over the line -- do we really want annotations stuffed full with little mini-method bodies (or, not so mini)?) -------- Forwarded Message -------- Subject: Extending 15.28 to include toString() on an enum constant Date: Sun, 8 Jul 2018 20:43:00 -0400 From: Daniel Trebbien To: amber-spec-comments at openjdk.java.net One small idea I have for enhancing the Java language is to allow toString() on enum constants to be used in constant expressions, as long as toString() is not overidden, or if it is, the implementation returns a constant expression. There are two use cases I have in mind for this: 1. When using the SLF4J logging library, if you want to embed the name of an enum constant in the log message, you should use parameterized logging to avoid incurring a wasted runtime string concatenation if logging at the specified level is disabled. See SLF4J's FAQ for "What is the fastest way of (not) logging?": https://www.slf4j.org/faq.html#logging_performance As an example of this in the wild, I submitted a pull request in which I converted a log statement involving an enum constant to parameterized logging: https://github.com/Netflix/eureka/commit/ad81a1140f351ec19165cb94d5aa668cfc08a932 There are other cases where an SLF4J logger call involving an enum constant correctly used parameterized logging, but I am not able to find an example right now. Although using parameterized logging solves the performance issue, it is desirable to keep down the number of parameters to an SLF4J logger call because the SLF4J Logger interface has more efficient variants of the trace(), debug(), info(), warn(), and error() calls that take zero, exactly one, and exactly two parameters. If a logger call passes at most two parameters, then the construction of an Object array to package the parameters into varargs is avoided. Needing to "waste" a parameter slot on an enum constant is undesirable. 2. When using Spring Security, it is possible to define an enum that lists the roles and other categories of permissions that are used by a Spring application. For example: package com.myapp.security; import org.springframework.security.core.GrantedAuthority; public enum AppAuthority implements GrantedAuthority { ROLE_USER, ROLE_ADMINISTRATOR; @Override public String getAuthority() { return toString(); } } When using the org.springframework.security.access.annotation.Secured annotation to secure controllers or actions, it would be nice to be able to use an enum constant in the annotation's value, as in @Secured({ ROLE_ADMINISTRATOR.toString() }); however, this is currently not valid Java code because ROLE_ADMINISTRATOR.toString() is not a constant expression. Instead, the name of the role must be duplicated: @Secured({ " ROLE_ADMINISTRATER" }). This is undesirable because it is error-prone and makes refactoring more difficult. It is also more difficult to find usages of a particular authority. If toString() on an enum constant were allowed within a constant expression, then finding usages of a particular authority would be a "Find Usages" operation in an IDE. From brian.goetz at oracle.com Mon Jul 9 13:10:59 2018 From: brian.goetz at oracle.com (Brian Goetz) Date: Mon, 9 Jul 2018 09:10:59 -0400 Subject: Extending 15.28 to include toString() on an enum constant In-Reply-To: References: <73648976.40631.1531118382273.JavaMail.zimbra@u-pem.fr> Message-ID: <26d97a10-f1d9-6f39-01cc-1a7847c1d17c@oracle.com> I doubt 303 will ever be able to constant fold a non-final virtual method in this manner.? Enums can override toString(), and can do so via separate compilation; this seems like it would be too big of a surprise to users.? Virtual methods are much riskier to constant fold than static ones (in part, because it's action-at-a-distance; a declaration modifier on a supertype causes folding of a method in a subtype.) On 7/9/2018 4:52 AM, Maurizio Cimadamore wrote: > Remi is correct - 303 has the potential to special case toString() > method calls on enums. One thing that 303 lacks, at least at the > moment, is the ability to redefine what goes into places where a > constant expression is expected (case labels, annotations, ...). That > is, the additional constant propagation occurs *after* type-checking, > and it's mostly there to support code generation. What you ask would > have an impact on the language frontend (and would therefore require > some spec text for it) - I'm unsure as to whether this falls within > the scope of 303. > > Maurizio > > > On 09/07/18 07:39, Remi Forax wrote: >> JEP 303 (http://openjdk.java.net/jeps/303) allows to build such kind >> of constants, i don't know if it works in the context of annotations >> but it's a nice use case. > From john.r.rose at oracle.com Tue Jul 10 00:19:40 2018 From: john.r.rose at oracle.com (John Rose) Date: Mon, 9 Jul 2018 17:19:40 -0700 Subject: Extending 15.28 to include toString() on an enum constant In-Reply-To: <26d97a10-f1d9-6f39-01cc-1a7847c1d17c@oracle.com> References: <73648976.40631.1531118382273.JavaMail.zimbra@u-pem.fr> <26d97a10-f1d9-6f39-01cc-1a7847c1d17c@oracle.com> Message-ID: <9C32988B-1310-4BCF-8CC6-6AA882FE2D89@oracle.com> On Jul 9, 2018, at 6:10 AM, Brian Goetz wrote: > > Virtual methods are much riskier to constant fold than static ones (in part, because it's action-at-a-distance; a declaration modifier on a supertype causes folding of a method in a subtype.) As a halfway point between general virtuals and statics, virtuals in final classes or sealed hierarchies are more like statics than not. The risk of action at a distance is that the class would be de-finalized or the hierarchy would be un-sealed, thus turning the virtual API point into a dynamically resolved method. Maybe enums could live in the halfway point, since they are final and/or sealed. A second problem with virtuals relative to statics is they are dependent on the receiver type, so for sealed (not final) classes, the static compiler might not be able to decide on the concrete type of an operand. That can be special cased for enums also. enum Foo { // Foo is sealed; Foo$Bat is final Bar, Baz, Bat { public String toString() { return "Bat, actually"; } }; public String toString() { return "a Foo"; } } ? John From dtrebbien at gmail.com Tue Jul 10 18:47:09 2018 From: dtrebbien at gmail.com (Daniel Trebbien) Date: Tue, 10 Jul 2018 14:47:09 -0400 Subject: Extending 15.28 to include toString() on an enum constant In-Reply-To: <57aa3237-3466-df7e-2603-5528e0bba21f@oracle.com> References: <57aa3237-3466-df7e-2603-5528e0bba21f@oracle.com> Message-ID: On Mon, Jul 9, 2018 at 8:55 AM, Brian Goetz wrote: ... > That said, there are some other operations that are far more deserving of > better compile-time treatment. In the context of raw string literals, we > expect the `align()` call to be common; given that `align()` is pure, > evaluating it at compile time rather than run time will be a big win. You > should expect to see this sort of thing coming out of JEP 303. (Though I > doubt it would go as far as `toString()` on enums, because at compile time, > we cannot prove that _at run time_ `toString()` would not have been > overridden. Constant-folding of static methods is far less problematic > than for virtual methods.) > > > You raised a second case: constants in annotations. This is very > different in character from the first case. The first case is a pure > quest-for-performance; hoping that the compile/runtime can optimize > something better. The second is looking for language changes to make > annotations more expressive; extending the notion of "constant expression" > so more expressions can be used as annotation parameters. We've actually > thought about this quite a bit in the context of JEP 303. > > My conclusion is: this would be a bad idea. It's great if the compiler > can opportunistically spot opportunities to eliminate computation, but > tying the semantics of a high-level language construct to this is pretty > dangerous. It means that in order to correctly reason about what can go in > an annotation, every developer must be able to correctly reason about all > the optimizations a compiler might do -- which is clearly a recipe for > frustration and confusion. > > Additionally, I thing the resulting language is not one we'll want to > program in. When you pull this string to the end, you will end up with > complex mini-programs as parameters to annotations. But annotations are > for metadata, not carriers for mini-programs. > > (We also confronted this from another angle; it has recently become > practical to allow putting (non-bound) method references in annotations, > which is a reasonable fit for the role of annotations. But the obvious > next question is: what about lambdas? And while the machinery is the same, > this is almost certainly over the line -- do we really want annotations > stuffed full with little mini-method bodies (or, not so mini)?) > That's a good point about the toString() implementation changing between compilations. If a class SomeController is compiled against an AppAuthority enum whose toString() implementation returns "something", and then the enum is recompiled with a different toString() implementation that returns "something_else", then the first compilation of SomeController is outdated. In such a scenario, it would be useful to have some sort of runtime error diagnostic, but this, I think, would be the start of a One Definition Rule in Java which probably isn't a great idea. Could JEP 303 cover Enum#name() , since it's non-overridable? Maybe name() could then be used within constant expressions. One difficulty with allowing name() to be used in constant expressions is providing a diagnostic if the enum is recompiled to remove an enum constant that was inlined into a constant expression in some other compilation unit. By way of example, suppose we have AdminController as follows: @Controller @RequestMapping("/admin") @Secured({ AppAuthority.ROLE_ADMINISTRATOR.name() }) public class AdminController { //... } .. and then AppAuthority is modified to remove the ROLE_ADMINISTRATOR enum constant. In such a scenario, I think that there should be some sort of LinkageError thrown when the AdminController class is loaded by the JVM.