15 things you learn about Java for OCA exam

It is fairly controversial to take Oracle’s Java certificates. One of the very vocal opponents of them in the local Java scene is Wojciech Seliga, who claims that he noticed that people with certificates performed worse at job interviews at Spartez than those that don’t have them (around 4:15). Even with such claims, I decided that I want to pass OCJP this year as I thought that it might be a good idea to review my Java fundamentals knowledge and make sure I don’t miss anything. What surprised me a bit is that with Java 8, the certification process is different than a few years ago and now one needs to first pass an OCA exam. At first, I was a bit dismissive – come on, this is just an exam that shows you how to write for loops – but then I took an example exam and scored… 25%.

So I learned. One important thing to notice is that Oracle’s Java exams test if you can be a compiler – there are multiple cases where they aim to trick you into parsing something that won’t compile. One can be surprised how much caveats there might be and that’s where a good point is to read a good book that prepares for an exam. I read a book by Jeanne Boyarsky and Scott Selikoff and highly recommend that one. The benefit of those preparations is that I structured some of the core Java knowledge – some things I haven’t yet seen in practice (thanks to Flying Spaghetti Monster!) as they aren’t usually good code examples – but at least when I see it in some legacy project in future I won’t run away screaming. Some of them are just something that’s easy and quite obvious, yet it can surprise.

Examples below aim mostly for junior/wannabe developers, but they might be a good refresher also for a developer with some experience. You can see all examples in my Github repository.

1. Can we use a different args name in main() method?

Yes, we can! The name can be any valid Java identifier.

2. Will that code compile?

Yes. We can have only one public class in the file and the file is named just as the public class.

3. What will be the output?

The output is 1. Number variable will be first assigned 2, then 3, then 1. With 3 you can see a static block initialization.

4. That’s a legal number?

A nice, fancy way to write 1000000.000222. Usually used to separate by three numbers, like int result = 1_000_000. Underscores cannot be at the beginning, end and around dot sign.

5. What will that code print?

A trick one. We abuse the fact that assigning a variable returns the variable. The result will be Hello!. It would work that way only with boolean. I highly discourage you from doing that.

6. Which statements are valid?

Line 5 is fine. Same with line 6 – we assign a value to s1 and s2 is declared without a value. Line 7 does not compile – we cannot declare variables with two types in one statement – even if the type is actually the same. Line 8 is okay, it’s just two statements in one line. Line 9 – does not compile. We didn’t provide a type for i4. If we declared i4 somewhere above with a type, it would be fine.

7. Why doesn’t this compile?

Division of two shorts gives us an int that cannot be implicitly cast to short. We need to explicitly do the casting:

8. Does this compile?

Nope. The first line is an int because it’s outside short’s range. Second one lacks an L sign at the end and is too large to be an int. BTW, did you know that you can add plus signs before numbers? Not that it’s helpful, but you can 😉

9. What will that code return?

Well, it won’t return anything because it won’t compile! In Java 8, one cannot switch on long and boolean types. In Java 7, switch on String was added that also previously wasn’t possible.

10. What will be the output?

The output here is:

Weekday
Saturday

Note that we use a static code block for the output. The main trick is that we put default not as the last one (as you would expect) and we forgot to put a break; there.

11. What does this code output?

1234
5

We use a label to break out of two for loops at once. Feels a bit like goto, but can be used only in certain cases.

12. Are these strings the same? What will be the output here?

true
false
true
true
true
false

In this case I’ll guide you to a good answer on string constant pool from StackOverflow. One more thing to notice is that this pool is an implementation of Flyweight design pattern.

13. Can we get a new dog? What will be the result of running this code?

Exception in thread "main" java.lang.UnsupportedOperationException
	at java.util.AbstractList.add(AbstractList.java:148)
	at java.util.AbstractList.add(AbstractList.java:108)
	at pl.mmkay.oca.Level13ListFromArray.main(Level13ListFromArray.java:12)

Arrays.asList creates an array-backed List implementation. In that one we cannot add or remove elements. We could only replace an element. That’s why we needed to create a new ArrayList to add a dog.

(That one is actually a real-life example, in a flat that I currently rent with my wife, we have a contract saying that we cannot have more than 2 pets at a time ;))

14. What will be the output here?

1
-2

It’s good to know what Arrays.binarySearch return values are. If an element is found, it will return an element’s index. If not, it will return a negative number that is

 -1 * index - 1 

where index is what would be the index of this element if it was in the array.

Important thing here is that array must be sorted beforehand! If it’s not, the results might be quite surprising.

15. Which element will stay in the list?

The only one that will stay will be 1. There are two remove methods in List class:

remove(int index)
remove(Object o)

For the first removal, the best match was the one with index. The second one looked for the right object.

That’s all, folks!

Hope you liked the examples. Now you know a bit more on how to act like a compiler.

Matchlogger update: I can add teams now!

I did quite a lot today. From working login, I went to being able to add teams through the user interface. All code changes can be seen in today’s pull request.

Tables and entity classes for countries and teams

I started with a database table for country information. I decided that this one will be (for now) managed only through Liquibase changesets, as I expect that country list will be static. For the beginning, there’s only one country (Poland), but I already have a task to add more. Each of the countries consists of name, some country codes (ISO-3166-1, FIFA, IOC) and a link to flag picture from Wikimedia Commons.

My structure for teams starts simple and is likely to grow. We’ve got a name, country and a link to team’s crest (logo). Right now I don’t store pictures, just links to them. This will likely change in future, but that requires a decision on how to store them – something that is a good topic for another post 🙂

Vue.js attempt

I must admit that I had some issues with Vue.js. My first idea was to create a REST API returning team list, load them with Vue.js and present records in a table with Angular-like syntax. I must have overlooked that before, but it turns out that core Vue cannot trigger AJAX calls and needs to use a separate library for that. One has several options, starting with vue-resource, up to jQuery. I decided to start with jQuery, as I already was importing it for Bootstrap JS features. Turned out that fighting with what it looked like a simple „for each row print <tr> and three <td> tags” took me three hours after which I decided that for this module, I will go the known way and implement it with Thymeleaf.

With Thymeleaf, the structure of the application is different. We don’t provide a REST API but insert needed values on backend side using a Model object instead. The templating engine works fairly similar to what I wanted with Vue.js though, so while I don’t remove Vue yet, I’ll start with Thymeleaf and read more on Vue in the meantime.

Thymeleaf layout

Thymeleaf has its benefits – one of them is a fragment-based layout. I now have a structure where layout.html defines the core layout and each of pages doesn’t have to include a header, footer, core CSS and JS files all over again. Of course, as I’m a lazy developer that wants to start with something that looks decent and is responsive, I started with Bootstrap that I aim to customize when I get the functional part done.

So, how does the team list look like?

The user is able to add a new team, define a country (from a long list that includes Poland, Poland and… Poland), add a link to a crest picture and that’s it. Not much, but it is a first real functional part of the application. More to come soon.

Spring Boot: Saving OAuth2 login data in DB using PrincipalExtractor

This post is a continuation of configuring OAuth2 login in Spring Boot. If you want to know how to configure the login itself, please take a look at the previous post.

As I mentioned previously, we want to save user login data in our database to be able to connect matches data with their users. We’re going to save only some basic data – the external id of the user from the provider to distinguish the user, her full name (that I want the user to be able to replace it with the nickname in the future), avatar and e-mail address. Let’s start with the database. As we already configured Liquibase, we are able to add a migration that will create the table in the DB:

As we have only one provider now, we could as well skip the login_type column. That would mean that if we add a new provider, we’d likely need to add this column and prepare migration that adds the value for existing records, so I decided that it’s a good idea to start with it. When we now start the application, the table is created in the database:

Next step is adding User entity class and its related Repository interface we’ll be using for DB access. As I wanted to use LocalDateTime for managing dates, but JPA doesn’t work that well with it yet, I needed to add Jsr310JpaConverters class to @Entityscan in my MatchloggerApplication class.

The last part was using PrincipalExtractor to obtain the data we want, actually save them into the database and mark that they will be used as principal data. The documentation of this class is virtually non-existent, but I found this example. I added a similar section to my WebSecurityConfiguration.java with just returning the same I received to check which data I am able to obtain.

That was the set of data provided by PrincipalExtractor. It appears that everything that I wanted to get is available here, but there is one potential issue I may come up with in future – as long as I have only one authentication provider, I know that those data come from Google, but if I have several providers and they provide different data, it might be the case that I’ll need to find out the provider based on some keys’ existence. Not the best option, but seems I need to stick with it for now (if anybody knows a better option, please let me know).

My WebSecurityConfiguration class looks like this now:

After adding the PrincipalExtractor, I am able to see that on successful login I have my first user in the database.

Let’s then modify the code that returns user data to use my new configuration:

After login, this is a current message that we see:

One note to add is that Java 8 LocalDateTime doesn’t look too nice in generated JSON response. I’ll likely convert the returned value into a timestamp in the future, depending on view layer’s needs.