Any risk using a single dollar sign `$` as a java class name? - java

Originally I was using the underscore _ as a class name. The new Java8 compiler complains that it "might not be supported after Java SE 8". I changed that to $, and there is no warning any more. However I remember that $ is used by Java to indicate an inner/embedded class in the byte code. I am wondering if there is any risk to use a dollar sign $ as a class name
Some background to this question. What I want to do is to overcome the fact that Java doesn't support pure function, and the _ or $ is to put an namespace to encapsulate some very generic concept (classes/static methods). and neither do I have a good name for this, nor do I want the lib user type too many things to reference that namespace. Here is the code showing what I am doing under the way: https://github.com/greenlaw110/java-tool/blob/master/src/main/java/org/osgl/_.java

It is bad style, and potentially risky to use $ in any identifier in Java. The reason it is risky is that the $ character is reserved for the use of the Java toolchain and third-party language tools.
It is used by Java compilers in "internal" class names for inner and nested classes.
It is used by Java compilers in the names of synthetic attributes.
It could be used by third-party code generators (e.g. annotation processors) for various purposes.
It could be used by other languages that target the JVM platform, and that might need to co-exist with your code.
You probably won't have technical issues with a plain $ classname at the moment (at least with respect to the standard Java toolchain). But there's always the possibility that this will change in the future:
They have (effectively) reserved the right to change this1.
There is a precedent for doing this in the _ example.
If you really, really need a one-character classname, it would be better to play it safe and use F or Z or something else that isn't reserved.
But to be honest, I think you'd be better off trying to implement (or just use) a real functional language than trying to shoe-horn a functional programming "system" into Java. Or maybe, just switch to Java 8 ahead of its official release. 'Cos I for one would refuse to read / maintain a Java codebase that looked like jquery.
I don't mean to create a functional lib for Java, just want to create a lib to maintain some common utilities I used. Again, I am a advocate of minimalism and feel suck with things like apache commons. The functional stuff is added to help me easier to manipulate collection(s).
If it is your code, you can do what you like. Make your own decisions. Act on your opinions. Be a "risk taker" ... :-). (Our advice on $, etcetera ... is moot.)
But if you are writing this code for a client or employer, or with the intention of creating a (viable) open source product, then you need to take account of other people's opinion. For example, your boss needs to have an informed opinion on how maintainable your code will be if you find a better paying job somewhere else. In general, will the next guy be able to figure it out, keep your code, fresh, etc ... or will it be consigned to the dustbin?
1 - JLS ยง3.8 states "The $ character should be used only in mechanically generated source code". That is saying "use it at your peril". The assumption is that folks who build their own source code generators can change them if the standard toolchain uses a bare $ ... but it is harder to change lots of hand written code, and that would be an impediment to upgrading.

Huh, you're right, using a $ in a classname works. Eclipse complains that it is against convention, but, if you are sure, you can do it.
The problem (conventionally) with using a $ is that the $ is used in the class hierarchy to indicate nested classes.... for example, the file A.java containing:
class A {
class SubA {
}
}
would get compiled to two files:
A.class
A$SubA.class
Which is why, even though $ works, it is ill advised because parsing the jars may be more difficult... and you run the risk of colliding two classes and causing other issues
EDIT, I have just done a test with the following two Java files (in the default package)
public class A {
private static final class SubA {
public String toString() {
return "I am initializing Nested SUBA";
}
}
private static final SubA sub = new SubA();
public A() {
System.out.println("What is " + sub.toString());
}
}
public class A$SubA {
#Override
public String toString() {
return "I am A$SubA";
}
}
public class MyMain {
public static void main(String[] args) {
System.out.println(new A());
System.out.println(new A$SubA());
}
}
And the code will not compile.....
Two problems, type A$SubA is already defined, and can't reference a nested class A$SubA by it's binary name.

Yes, to be pedantic about answering your question there is a risk. As some other folks have mentioned, it violates java naming conventions. So the risk is that with future versions of the JDK this may cause problems. But beyond that, and some issues if you try to use nested classes you should be fine.

I think you're trying to avoid ugly names like Util.andThen. Consider using static imports. That lets you import all the methods in the header import static org.ogsl.Util.*, so then you can simply use you andThen without any prefix at all.

The Selenide project does it. Just look at the top of this documentation:
https://selenide.org/documentation.html
Maybe it is a more acceptable thing to do only in test code.
API ref:
https://selenide.org/javadoc/current/com/codeborne/selenide/Selenide.html

Related

What are 'real' and 'synthetic' Method parameters in Java?

Looking into j.l.r.Executable class I've found a method called hasRealParameterData() and from its name and code context I assume that it tells whether a particular method has 'real' or 'synthetic' params.
If I take e.g. method Object.wait(long, int) and call hasRealParameterData() it turns out that it returns false which is confusing to me, as the method is declared in Object class along with its params.
From this I've got a couple of questions:
What are 'real' and 'synthetic' Method parameters and why Java believes that params of Object.wait(long, int) are not 'real'?
How can I define a method with 'real' params?
Preamble - don't do this.
As I mentioned in the comments as well: This is a package private method. That means:
[A] It can change at any time, and code built based on assuming it is there will need continuous monitoring; any new java release means you may have to change things. You probably also need a framework if you want your code to be capable of running on multiple different VM versions. Maybe it'll never meaningfully change, but you have no guarantee so you're on the hook to investigate each and every JVM version released from here on out.
[B] It's undocumented by design. It may return weird things.
[C] The java module system restriction stuff is getting tighter every release; calling this method is hard, and will become harder over time.
Whatever made you think this method is the solution to some problem you're having - unlikely. If it does what you want at all, there are probably significantly better solutions available. I strongly advise you take one step backwards and ask a question about the problem you're trying to solve, instead of asking questions about this particular solution you've come up with.
Having gotten that out of the way...
Two different meanings
The problem here is that 'synthetic' means two utterly unrelated things and the docs are interchanging the meaning. The 4 unrelated meanings here are:
SYNTHETIC, the JVM flag. This term is in the JLS.
'real', a slang term used to indicate anything that is not marked with the JVM SYNTETHIC flag. This term is, as far as I know, not official. There isn't an official term other than simply 'not SYNTHETIC'.
Synthetic, as in, the parameter name (and other data not guaranteed to be available in class files) are synthesised.
Real, as in, not the previous bullet point's synthetic. The parameter is fully formed solely on the basis of what the class file contains.
The 'real' in hasRealParameterData is referring to the 4th bullet, not the second. But, all 4 bullet point meanings are used in various comments in the Executable.java source file!
The official meaning - the SYNTHETIC flag
The JVM has the notion of the synthetic flag.
This means it wasn't in the source code but javac had to make this element in order to make stuff work. This is done to paper over mismatches between java-the-language and java-the-VM-definition, as in, differences between .java and .class. Trivial example: At least until the nestmates concept, the notion of 'an inner class' simply does not exist at the class file level. There is simply no such thing. Instead, javac fakes it: It turns:
class Outer {
private static int foo() {
return 5;
}
class Inner {
void example() {
Outer.foo();
}
}
}
Into 2 seemingly unrelated classes, one named Outer, and one named Outer$Inner, literally like that. You can trivially observe this: Compile the above file and look at that - 2 class files, not one.
This leaves one problem: The JLS claims that inner classes get to call private members from their outer class. However, at the JVMS (class file) level, we turned these 2 classes into separate things, and thus, Outer$Inner cannot call foo. Now what? Well, javac generates a 'bridger' method. It basically compiles this instead:
class Outer {
private static int foo() {
return 5;
}
/* synthetic */ static int foo$() {
return foo();
}
}
class Outer$Inner {
private /* synthetic */ Outer enclosingInstance;
void example() {
Outer.foo$();
}
}
The JVM can generate fields, extra overload methods (for example, if you write class MyClass implements List<String> {}, you will write e.g. add(String x), but .add(Object x) still needs to exist to cater to erasure - that method is generated by javac, and will be marked with the SYNTHETIC modifier.
One effect of the SYNTHETIC modifier is that javac acts as if these methods do not exist. If you attempt to actually write Outer.foo$() in java code, it won't compile, javac will act as if the method does not exist. Even though it does. If you use bytebuddy or a hex editor to clear that flag in the class file, then javac will compile that code just fine.
generating parameter names
Weirdly, perhaps, in the original v1.0 Java Language Spec, parameter types were, obviously, a required part of a method's signature and are naturally encoded in class files. You can write this code: Integer.class.getMethods();, loop through until you find the static parseInt method, and then ask the j.l.r.Method instance about its parameter type, which will dutifully report: the first param's type is String. You can even ask it for its annotations.
But weirdly enough as per JLS 1.0 you cannot ask for its name - simply because it is not there, there was no actual need to know it, it does take up space, java wanted to be installed on tiny devices (I'm just guessing at the reasons here), so the info is not there. You can add it - as debug info, via the -g parameter, because having the names of things is convenient.
However, in later days this was deemed too annoying, and more recently compilers DO stuff the param name in a class file. Even if you do not use the -g param to 'include debug symbol info'.
Which leaves one final question: java17 can still load classes produced by javac 1.1. So what is it supposed to do when you ask for the name of param1 of such a method? The name simply cannot be figured out, it simply isn't there in the class file. It can fall back to looking at the debug symbol table (and it does), but if that isn't there - then you're just out of luck.
What the JVM does is make that name arg0, arg1, etc. You may have seen this in decompiler outputs.
THAT is what the hasRealParameterData() method is referring to as 'real' - arg0 is 'synthesized', and in contrast, foo (the actual name of the param) is 'real'.
So how would one have a method that has 'real' data in that sense (the 4th bullet)? Simply compile it, it's quite hard to convince a modern java compiler to strip all param names. Some obfuscators do this. You can compile with a really old -target and definitely don't add -g, and you'll probably get non-real, as per hasRealParameterData().

Force Java compiler to assume that all variables are final

Is it possible -- via a compiler switch or a commonly used tool (which I do not know) -- to break a compilation if a variable is reassigned when not marked as a mutable keyword (which is not present in Java yet)?
Example:
Contract a; // compile error
Contract b = getContract(id); // ok
b.doSomething(); // ok
b = getContract(otherId); // compile error
mutable int i = 1;
i++; // ok
I know that there are languages are like this, but being forced to code java in a company, using such a tool is the only choice.
Greetings,
JG.
Take a look at CheckStyle static code analysis tool. You can also integrate it to your IDE.
FinalLocalVariable check looks like your case:
Checks that local variables that never have their values changed are
declared final. The check can be configured to also check that
unchanged parameters are declared final.
Also there is PMD source code analyzer. But I've never used it so cannot suggest anything.
No, you can't force a Java compiler to do that. And you can't put non-Java keywords (like mutable) into Java source code. No compliant Java compiler will allow either of these.
You could possibly use a custom annotation to "declare" mutable local variables, and use a static analyser to detect assignments to locals without the annotation.
There may even be existing analyser tools, annotations, etc that will do this for you, though I am not aware of a tool that exactly fits the bill.
(The FinalLocalVariable check for CheckStyle doesn't do exactly what you want. It will tell you where to add final to declarations, but that isn't what you are asking for ... I think. You want variables to be treated as final even if they are not explicitly declared as such.)
But in my opinion, it would be a bad idea to do this.
Your employer has made a decision (right or wrong) that Java is the only language you can use. One of the reasons for this will ensuring that the code that you develop can be maintained and enhanced by Java programmers. By using unusual notations so that you can write zero-assignment code, you are undermining company policy.
At best, you won't make yourself popular with your coworkers by doing this.

Simple Java code, having trouble creating a C++ equivalent (private static members and public accessor methods)

I'm a Java developer with 7 years of experience but I'm almost entirely new to C++. This isn't homework or even for real paid work. I'm just delving into C++ and having trouble emulating this one particular pattern that I use frequently in Java.
Basically (in Java):
public class ExampleManager
{
private static Example _example;
public static Example getExample()
{
return _example;
}
public static void setExample(Example example)
{
_example = example;
}
}
I've so far tried about four variants with what I've learned about C++. I found that passing 'example' with the same syntax gets me a copy of 'example' stored in the class. I understand most of the logic behind pointers, just not a lot of the specifics. This example would go a long way to help me with that.
If someone could give me equivalent C++ code to this so that I can break it down line by line and step through it, I would appreciate it very much.
I don't use this pattern as is in Java, but its the bones of the pattern I use to maintain thread safe access to single instance members.
The basically equivalent code in C++ would be this:
class ExampleManager
{
private:
static std::shared_ptr<Example> _example;
public:
static std::shared_ptr<Example> getExample()
{
return _example;
}
static void setExample(std::shared_ptr<Example> example)
{
_example = example;
}
};
It makes use of the std::shared_ptr class, which does most of the memory handling stuff for you (you only have to new objects, basically just like in Java).
We do not use "raw" pointers (i.e. Example *) here; usage of "raw" pointers is usually frowned upon (unless you're working in an environment with limited resoures, or close to hardware), since it gains you little in terms of performance but can lead to ugly problems (memory leaks, double deletions, ...) if not considered carefully.
Please note that the shared_ptr used above is only part of the standard since C++11. Most halfway recent compilers will already accept its usage like shown above; for some a bit older ones you might have to do special things:
e.g. for g++ <= 4.6, add -std=c++0x to compilation command line
for some you might have to use std::tr1::shared_ptr
if both of the above options fail, you can use boost::shared_ptr from the boost libraries.

Java mechanisms at use in lambdaj closures

Lamdbaj allows the definition of closures in the Java language, various examples can be found
here
My question is regarding the underlying Java mechanisms at use, for instance, to define the println closure, the following code is used:
Closure println = closure();
{ of(System.out).println(var(String.class)); }
This closure can be subsequently executed via:
println.apply("foobar");
I am curious as to what mechanisms in Java would allow the call to of(...).println(...) to become associated with the println instance itself.
Naturally, the lambdaj source code is available to read but I was hoping for a slightly higher level explanation if anyone has one. My reflection skills go as far as a bit of introspection and executing methods dynamically.
I am Mario Fusco and I am the main developer of the lambdaj library.
First of all I would like to clarify something: lambdaj is not intended to replace any functional language. As I said last week in my speech at the Jug of Zurich if you have a chance to use Scala, go for it and never look back. Here you can find a resume of my speech where it is clearly stated that:
http://ctpjava.blogspot.com/2009/10/lambdaj-new-trends-in-java.html
I am an happy Scala developer too. But sometimes you are just obliged to develop in Java (in my experience, in the real world, about the 80% of times you cannot choose in which language you have to write your code) and in this case some of the lambdaj features could be helpful (or I hope so). I just wanted to bring to Java some functional features that are totally missing. Of course the result is not completely satisfying mainly due to the limitation imposed by Java itself.
As for the internal lambdaj mechanism, yes it uses a ThreadLocal in order to achieve that result. If you have other questions, curiosities or even better suggestions and constructive critics about lambdaj maybe you could be interested to register yourself to the lambdaj mailing list here:
http://groups.google.com/group/lambdaj
Bye
Mario
Well, of is presumably a static method which is imported statically so it can be called without the enclosing class name. I expect that var is the same. Both methods must return some type which have the methods subsequently called:
public class Printable {
public void println(Var var);
}
public class Fac {
public static Printable of(Object o) {
return new Printable(o);
}
public static Var var(Class<?> clazz) {
return new Var(clazz);
}
}
All of a sudden:
Fac.of(System.out).println(Fac.var(String.class));
Is valid Java. Using static imports, hey presto:
import static Fac.*;
of(System.out).println(var(String.class));
The curly-braces are obviously valid Java as you can add these in any method to aid in defining a lexical sope. This API-design style is called fluent and is best showcased by the JMock testing library.
By the way, if this is supposed to introduce closures to Java, it's quite ridiculous - the syntax is unreadably awful. Their I/O example actually made me laugh out loud. Try Scala!
EDIT - the two println calls are associated I believe because the first sequence of calls allow the library to capture the variables which you have passed in as parameters. These are probably captured in some ThreadLocal structure. When you then call a (also presumably static) println method, the library is using this captured data to actually execute the behaviour at a later point. Also testing related, the EasyMock test framework uses a similar mechanism (which uses Java proxies in the background) to capture expected values.

Do java's Inner classes pose a security risk?

Recently the security team on my project released a secure code guidelines document, designed to be used as part of our code reviews. The first thing that struck me was an item that said "Do not use Inner classes". I thought this seemed like a very heavy handed and sweeping statement. Inner classes are good if used correctly right?, but i did a bit of googling and found this, quoted here for convenience.
Rule 5: Don't Use Inner Classes
Some Java language books say that
inner classes can only be accessed by
the outer classes that enclose them.
This is not true. Java byte code has
no concept of inner classes, so inner
classes are translated by the compiler
into ordinary classes that happen to
be accessible to any code in the same
package. And Rule 4 says not to depend
on package scope for protection.
But wait, it gets worse. An inner
class gets access to the fields of the
enclosing outer class, even if these
fields are declared private. And the
inner class is translated into a
separate class. In order to allow this
separate class access to the fields of
the outer class, the compiler silently
changes these fields from private to
package scope! It's bad enough that
the inner class is exposed, but it's
even worse that the compiler is
silently overruling your decision to
make some fields private. Don't use
inner classes if you can help it.
(Ironically, the new Java 2
doPrivileged() API usage guidelines
suggest that you use an inner class to
write privileged code. That's one
reason we don't like the
doPrivileged() API.)
My questions are
Does this behaviour still exist in java 5 / 6?
Is this actually a security risk, given that any class, other than the outer and inner classes, that tried to access the outer class' private members would not compile?
Does it pose enough of a security risk to warant the 'guideline' 'Do not use inner classes'?
This information is a around a decade out of date. The widespread use of anonymous inner classes with AccessController.doPrivileged should be a clue. (If you don't like the API, consider the proportion of try-finally blocks that are incorrectly missing in the JDK.)
The policy is that no two class can share the same package if they are loaded by different class loaders or have different certificates. For more protection, mark packages as sealed in the manifest of your jars. So, from a security standpoint, "Rule 4" is bogus and hence also this rule.
In any case, working out security policies you should understand what you are protecting against. These sorts of policies are for handling mobile code (code that moves) that may have different levels of trust. Unless you are handling mobile code, or your code is going into a library that may be required to, there is very little point in these sorts of precautions. However, it is almost always a good idea to use a robust programming style, for instance copying and validating arguments and return values.
Does this behaviour still exist in java 5 / 6?
Not exactly as described; I've never seen a compiler where this was true:
In order to allow this separate class access to the fields of the outer class, the compiler silently changes these fields from private to package scope!
Instead IIRC Sun Java 3/4 created an accessor rather than modifying the field.
Sun Java 6 (javac 1.6.0_16 ) creates a static accessor:
public class InnerExample {
private int field = 42;
private class InnerClass {
public int getField () { return field; };
}
private InnerClass getInner () {
return new InnerClass();
}
public static void main (String...args) {
System.out.println(new InnerExample().getInner().getField());
}
}
$ javap -classpath bin -private InnerExample
Compiled from "InnerExample.java"
public class InnerExample extends java.lang.Object{
private int field;
public InnerExample();
private InnerExample$InnerClass getInner();
public static void main(java.lang.String[]);
static int access$000(InnerExample);
}
$ javap -classpath bin -c -private InnerExample
static int access$000(InnerExample);
Code:
0: aload_0
1: getfield #1; //Field field:I
4: ireturn
Is this actually a security risk, given that any class, other than the outer and inner classes, that tried to access the outer class' private members would not com[p]ile?
I'm speculating a bit here, but if you compile against the class it doesn't, but if you add the access$000 then you can compile code which uses the accessor.
import java.lang.reflect.*;
public class InnerThief {
public static void main (String...args) throws Exception {
for (Method me : InnerExample.class.getDeclaredMethods()){
System.out.println(me);
System.out.printf("%08x\n",me.getModifiers());
}
System.out.println(InnerExample.access$000(new InnerExample()));
}
}
The interesting thing is that the synthesised accessor has modifier flags 00001008 where if you add a package level static method it has flags 00000008. There's nothing in the second edition of the JVM spec for that flag value, but it seems to prevent the method being seen by javac.
So it appears that there's some security feature there, but I can't find any documentation on it.
(hence this post in CW, in case someone does know what 0x1000 means in a class file)
Yes, this behavior still exists.
It is a security risk because the rogue class could be crafted with something else than the standard javac.
It depends of how much paranoid you are :) If you don't allow alien classes to run in your JVM, I don't see the problem though. And if you do, you have bigger problems (sandboxes and all)
I know you only had 3 questions, but like other people here, I think this is a stupid restriction.
Does this behaviour still exist in java 5 / 6?
You can use the javap tool to determine what your binaries are exposing and how.
package demo;
public class SyntheticAccessors {
private boolean encapsulatedThing;
class Inner {
void doSomething() {
encapsulatedThing = true;
}
}
}
The above code (compiled with Sun Java 6 javac) creates these methods in SyntheticAccessors.class:
Compiled from "SyntheticAccessors.java"
public class demo.SyntheticAccessors extends java.lang.Object{
public demo.SyntheticAccessors();
static void access$0(demo.SyntheticAccessors, boolean);
}
Note the new access$0 method.
You should consider what kind of security your application has to provide. An application with a secure architecture won't run into these named issues.
If there is something an user is not allowed to do with your code, you have to seperate this functionality and run it on a server (where the user has no access to the class files).
Remember that you can always decompile java class files. And don't rely on "security by obscurity". Even obfuscated code can be analyzed, understood and modified.
Malicious code can use java reflection to get to any piece of information in the JVM unless a security manager is in place which prohibits this, this includes changing private fields to public and much more.
My personal opinion is that the reasons not to, are overwhelmed by the other possibilities, so if you need it, it makes sense, and it is readable, use inner classes.
The idea of this kind of security in code is kind of silly. If you want code level security, use an obfuscation tool. Like #skaffman said in the comments above, "Code visibility has never been a security feature. Even private members can be accessed using reflection.".
If you are distributing your compiled code and not obfuscating it, then using an inner class is your last worry if you are worried about people tinkering with your privates.
If you are hosting your code, then why are you worried about someone poking around your inner classes?
If you going to linking some 3rd party code you don't trust and can't check at run time, then sandbox it.
Like I said above, if this is really a policy at your company, please promptly report your company to thedailywtf.com
"Is this actually a security risk, given that any class, other than the outer and inner classes, that tried to access the outer class' private members would not compile?"
Even if it won't compile under normal circumstances, you can still generate your own bytecode. But that's no reason to avoid inner classes. All you would have to do is assume all your inner classes are public.
If you really want to be able to run untrusted code, learn how setup your own sandboxes and security levels using The Java Security Architecture, it's not that hard. But mostly, you should avoid running random code in a secure environment.
nonsense! follow the same logic, do not write public methods either, because they have access to private fields, gush!
Note that the drawbacks listed do not hold for static inner classes as they do not have implicit access to their enclosing class (or object really.)
So if this rule is going to help up in your company, it might be an idea to get static inner classes excempted as they offer a way for encapsulation which is useful in many cases.
#Tom, quoting the Java language specification, "Member classes may be static, in which case they have no access to the instance variables of the surrounding class"

Categories

Resources