Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use diamond operator in jOOQ code #8932

Closed
lukaseder opened this issue Jul 10, 2019 · 11 comments
Closed

Use diamond operator in jOOQ code #8932

lukaseder opened this issue Jul 10, 2019 · 11 comments

Comments

@lukaseder
Copy link
Member

lukaseder commented Jul 10, 2019

jOOQ still supporting Java 6 in the commercial distributions has an impact on jOOQ's internals, where some language features are forbidden to be used by jOOQ. One such feature is the diamond operator:

// Possible in Java 6
List<String> list = new ArrayList();
List<String> list = new ArrayList<String>();

// Not possible in Java 6
List<String> list = new ArrayList<>();

Not being able to use the diamond operator can be quite cumbersome, especially in the presence of jOOQ's generics, e.g.

// Having to write
methodAcceptingRecord2StringString(new ArrayList<Record2<String, String>>());

// ... instead of
methodAcceptingRecord2StringString(new ArrayList<>())

Our Java 6 code base, however, is completely derived from our commercial Java 11 code base. We search-replace a lot of tokens to make the Java 6 build compile. We could, of course, replace all "<>(" tokens in .java files by "(", which would produce raw type constructor invocations instead of generic ones. This should mostly work. Where it doesn't we can revert to explicitly using the type witness.

Where does this approach not work?

  • Anonymous class instantiations (this works only from Java 9 onwards)
  • When generic exceptions are omitted, in case of which a checked exception might be inferred
  • Edge cases where Java 6 was just not good enough
  • Edge cases where the Eclipse compiler and javac disagree

A regex to find candidates for the diamond operator: new [\w.]+<\w+(?!.*\{$)

@knutwannheden
Copy link
Contributor

Doesn't the compiler produce the same bytecode in all cases? Since we aren't compiling with JDK 6 anyway (and thus don't necessarily have that as a requirement), I wonder if the JDK 8 can't compile the diamond operator while targeting Java 6.

@lukaseder
Copy link
Member Author

I wonder if the JDK 8 can't compile the diamond operator while targeting Java 6.

We've already had that. You cannot have a source version lower than a target version, because this isn't just about the language features...

@lukaseder
Copy link
Member Author

But the workaround is really simple, and so far, I've not seen any big issues (see the list in the original text) after around 200 refactorings, while I'm testing...

@knutwannheden
Copy link
Contributor

What I meant was have source as 8 and target as 6 and use the animal sniffer or a JDK 6 rt.jar to guard against too new APIs. But maybe that doesn't work...

@lukaseder
Copy link
Member Author

Well, one issue that we didn't have before and that we will have if we go forward with this is syntax that is supported in Java 11 but not in Java 8 :-P

@lukaseder
Copy link
Member Author

What I meant was have source as 8 and target as 6

I know what you meant. That's not possible

lukas@LAPTOP-VH130UJV MINGW64 ~
$ cat Test.java
class X {
        static class Y<T> {}
        void m() {
                Y<Integer> y = new Y<>();
        }
}

lukas@LAPTOP-VH130UJV MINGW64 ~
$ javac -source 8 -target 8 Test.java
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8
warning: [options] bootstrap class path not set in conjunction with -source 8
1 warning
lukas@LAPTOP-VH130UJV MINGW64 ~
$ javac -source 8 -target 6 Test.java
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8
warning: source release 8 requires target release 1.8

@knutwannheden
Copy link
Contributor

Too bad.

@lukaseder
Copy link
Member Author

You're probably not the first to say that :-)

Anyway. This is so strikingly simple, and there are only very few rules to obey, I'll just go ahead and do this.

@knutwannheden
Copy link
Contributor

I think this looks a bit too adventurous, but cool nonetheless: https://github.com/luontola/retrolambda

@lukaseder
Copy link
Member Author

I had played around with this project a long time ago. I found it broke apart quickly when type inference requirements were more complex. Lambdas aren't just about bypassing the anonymous class allocation, they're also a lot about type inference.

But it's been a long while, and there had been some maintenance work in this project (not much, unsurprisingly), so maybe, it's indeed worth another shot. We could profit occasionall from using lambdas, but I'm not too optimistic. Also, compared to the diamond operator, the advantage in jOOQ's internals is probably not as impressive.

@lukaseder
Copy link
Member Author

I've now replaced ~98% of all constructor type witnesses (not sure if they're called that way) by the diamond operator. Locally, the jooq-pro / jooq-pro-java-6 / jooq-pro-java-8 builds all compile and tests pass.

I'm really excited about this improvement! Crazy to think that this could've been done many years ago :)

@lukaseder lukaseder changed the title Start using diamond operator in jOOQ code Use diamond operator in jOOQ code Jul 11, 2019
lukaseder added a commit that referenced this issue Jul 16, 2019
These method calls use fully qualified constructor calls, which is why they had been overlooked.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants