Categories
Programming Projects

List of Quirks when using Spring Framework and Kotlin

I’m not used to the JVM environment. Usually I use NodeJS, Ruby with Rails or PHP with Laravel. But after awhile, I find these dynamic programming environment quite problematic, especially on a large project. Rails is simply too magical, it is dark magic. Sure, it have a nice syntax, but debugging them is quite a hell and no type safety means you really need to unit test your software. PHP and Laravel is not that bad actually, but when the things that makes it nice came from statically typed language, like type hints and IoC container, why not just use a true statically typed language? NodeJS have quite a lot of things. You can have type safety with typescript. You probably can get an IoC container… if you want to use them. But the whole NodeJS environment is way too immature and changes too quickly making it feels quite brittle. Update a package and the whole thing could collapse. Not too mention typescript support really depends on the library maintainer. Its the same case for flowtype too. Except I had worse luck with it.

So, when you want to use a statically typed programming language to make a web application, two things came to mind: C# and Java. Other languages are too not-mainstream enough. With C#, you have .NET MVC and with Java, you have Spring, Jersey and Play framework. The open source version of .NET which is .NET Core is simply too immature. So whats left is Java. Java is quite tedious, but luckily, we have Kotlin, which is another programming language running on top of the JVM with very high interoperability with Java. In the choice of framework, Play framework utilize Akka which is way too different than conventional application. Jersey is actually quite nice, but it does not have a built in integration with other things. Spring is the most famous of them all, so its not that hard to choose, its just that it could be overwhelming.

First of all, what is Spring framework? You need to get this right real quick, because the libraries built around it is quite a lot. At its core, the Spring framework by itself is only an IoC container. Spring MVC is a web framework that have the Model-View-Controller architecture that we want. Spring Data is an umbrella project for data access related things and among those is Spring Data JPA which provides integration with JPA (Java Persistence API) which is a java specification for ORM (Object Relational Model). Spring Data JPA utilizes Hibernate which is a JPA implementation.

Now do you see what I mean by overwhelming? All of these libraries are configured by declaring a Configurer bean. A bean is basically a fancy way of saying class/object with specific structure. You can also configure through XML, but that is old school technique which result is a huge mess of XML. The new way is too declare a Configurer class and configure it with code. In general you’ll probably use a ConfigurerAdapter instead, because Configurer is an interface and you don’t want to configure everything. But still, that is a lot of configuration. Which is why they created Spring Boot, another project which is basically a collection of configurations of these libraries. Spring Boot will detect if you include these library and will automatically apply a default reasonable configuration. ‘reasonable’ does not mean convenient, or in some sense even reasonable. I guess a better word is ‘compatible’ or ‘safe’. Still, it is too invaluable that you probably should google ‘Spring Boot’ instead of ‘Spring Framework’. But what if you want to adjust some parameters of some library? Well, it could be that Spring Boot have already enabled the use of configuration files. Which by default is usually application.properties. But you can also use YAML. I’m not exactly sure the file name for that. But what are the settings? Here comes the problem with Spring framework in general: the only documentation is its user guide/reference and those references are very long. That, or you go through the source code of Spring Boot or the respective library, which are Java code, which are very long.

Once you get through those long and tedious readings, assuming nothing goes wrong, you get the ability to:

  • Create an MVC controller by annotating arbitrary class, with the base path and so on.
  • Declare a a bean which is an interface that extends CrudRepository<Model, Int> where Model is your arbitrary POJO (Plain Old Java Object) that have certain annotations that declare it as a model. And inject it to your arbitrary other bean (like your controller), gaining a free implementation of your interface that interface with your database.
  • Include liquibase in your gradle, then just declare your migration in resources/db.changelog/db.changelog-master.yaml.
  • Ability to map http body to arbitrary object, effectively parsing JSON request to a POJO, with a single annotation.
  • Return a POJO from your controller method, and it will automatically convert it to JSON.
  • Annotate your POJO with java.validation annotations and annotate your POJO controller parameters with @Valid and it will throw error if the JSON send does not validate.
  • Ability to annotate your bean method with a security expression, and it will throw error if it does not pass.
  • Java’s plain simple and conventional generic and inheritance model.
  • Probably other things too.

If that sounds quite magical, well it is. Maybe too magical, that if somethings goes wrong, you don’t know what happen. Good thing its all mainly Java code, so you got nice IDE support for debugging. But its a whole lot of Java code. A whole lot.

Of course, its not all good. Some of it is quite bad actually. The template is JSP which I’m not a big fan off. You can’t easily rollback your database. I use it mainly for a rest controller. Unfortunately in that regard, Jersey brings more things out of the box. When a validation error happen, it does not report it as a nice JSON. Jersey does that nicely. When a resource is not found and so it fails to bind the resource as parameter, it simply pass an empty resource. Jersey return a nice 404. And of course, when something goes wrong, I’ll take a day or two to find the problem. So here is a list of problem/quicks I found so far. I’ll probably update it as I found more issues.

It is asking for a password, some csrf validation error? And CORS issues.

By default, the spring boot configured spring security will ask for password, which is randomly generated. CSRF protection is enabled, not really useful for REST. Also, CORS will need to be allowed. So I used these config to overcome those issues.


import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
import org.springframework.web.cors.CorsConfiguration
import org.springframework.web.cors.CorsConfigurationSource
import org.springframework.web.cors.UrlBasedCorsConfigurationSource
import javax.inject.Named

/**
 * Created by amirul on 31/05/2017.
 */
@Configuration
@EnableWebSecurity
class WebSecurityConfig: WebSecurityConfigurerAdapter() {
	override fun configure(http: HttpSecurity) {
		http
			.cors().and()
			.csrf().disable()
			.authorizeRequests()
			.anyRequest().permitAll().and()
	}

	@Bean
	fun corsConfigurationSource(): CorsConfigurationSource {
		val configuration = CorsConfiguration();
		configuration.allowedOrigins = listOf("*");
		configuration.allowedMethods = listOf("GET","POST" ,"PATCH");
		configuration.allowedHeaders = listOf("*");
		val source = UrlBasedCorsConfigurationSource();
		source.registerCorsConfiguration("/**", configuration);
		return source;
	}
}

Model Validation does not work with kotlin.

If you use a data class with the constructor arguments, make sure you annotate the field instead of the getter/setter with something like @field:NotBlank.

In a one to many column relationship, on save, the child’s foreign key is not set, and I’ve specify it in database as non-null, so it will crash.

In a a JoinColumn annotation, make sure you specify nullable = false, like this @JoinColumn(name= "parent_id", nullable = false)

In a one to many relationship, if I remove the child item from the array from the parent object and save the parent, the removed child is not removed in the database.

In the @OneToMany annotation, make sure to set orphanRemoval to true.

I’m getting `org.hibernate.HibernateException: A collection with cascade=”all-delete-orphan” was no longer referenced by the owning entity instance:`.

Yea… the collection in the entity is pretty special. So you can’t just assign them and hope the complex datamapper technique to work. So don’t replace the collection object itself. Call clear and addAll instead.

I’m getting `org.hibernate.AnnotationException: Collection has neither generic type or OneToMany.targetEntity()`.

Try not using Kotlin’s immutable List. Which is the default list. Use MutableList instead. Yeah, I know Hibernate does not play well with immutable data types at all.

Categories
Programming Projects

Thru Earth Position

Assalamualaikum everyone,

People in US usually said that “China is halfway around the world”, which means that, (given that the earth is round) if you want to point where where is China, you would point it straight underground. I wonder, what about other part of the world? Do North pole also go down? How far down? So I made an app for it called “Thru Earth Position”.

hires
A poor man’s logo.

Why “Thru Earth Position”? The answer is mainly because I can’t figure out a better name. It was originally an augmented reality experiment on how to map location on earth to the screen. Or in another word, I want to move around the screen and the screen will show what location is in front of me. It work, and I thought it was cool, so I made another one, with a 3D globe-like interface. For some reason, the addition of 3D globe visual kinda reduce the feel of AR-ness. 

Screenshot_2016-08-15-15-24-47
Something feels off…

That, or mainly because I’m generally a bad designer. The app also shows the distance from your current position. It is relatively simple, with some settings do show or hide elements. It does not use the internet aside from google maps and geocoding to fetch the location name.

The app is actually my first ‘kinda-proper’ mobile application. It is made using libgdx(an OpenGL game framework) and Kotlin(a Java compatible programming language). So, it is kinda an experiment on “making an android app using Kotlin and libgdx with some OpenGL stuff”. It is available on google play store. Which means, it is also another experiment on “what happen when you make a relatively simple app and publish it”. You can find it here. Try it out, and let me know what you think about it.

Categories
Programming Projects

Rails-Devise-Warden Token Authentication + Android’s Volley

Hi, recently I’m trying to make an android app that uses a rails server. I used to code REST server before, but that is for javascript apps. Not android. And now that I’m trying to do so, I found a problem. Whenever the devise authenticate_user! failed and it throw 401 to the android app, Volley complain that some form of challenge key is missing. It work fine with a browser and it responded with an error in json form. This is the normal Devise behavior, which seems to also have support for api server. Because of the error in Volley, I can’t get the JSON that contain the error in order to show the message.

For the impatient one, the solution is this:
[ruby]

Devise::FailureApp #Autoload it

##
# Patch failure app so that the WWW-Authenticate message is sent regardless if using http_authenticatable.
class Devise::FailureApp < ActionController::Metal
alias :old_http_auth :http_auth
def http_auth
old_http_auth
self.headers["WWW-Authenticate"] = %(Basic realm=#{Devise.http_authentication_realm.inspect})
end
end

[/ruby]

Put this in an initializer. Another thing is that, make sure that Volley tells Rails that it is accepting a json response, through HTTP Headers or ‘.json’ postfix.

The reason for the Volley error is that, when an HTTP server respond with HTTP 401, it is expected to respond with “WWW-Authenticate” header. The spec indicate that it MUST respond so. The problem is, the browser treat this header as an indicator to show user an HTTP Basic Authentication form, which is not always what we want. We just want to respond with 401 to indicate that the user is unauthorized for that particular resource. We can’t really use 403 because that means, Forbidden, a different meaning. Showing a 200 with an error message/json just feels too hackish for an api server. Because of this, devise did not send the header if the model did not enable http basic authentication.

By default, Devise sent out a 401 when it detect that the request is not of a ‘navigation’ format. By default that is [*,:html], which as far as I understand, every format and html. Or in another word, everything. For those of you who have problem with setting up Devise for an api server, change this to [:html] and make sure your client application properly indicate its accepted format. Using this, which basically means nothing else but the patch above, my api server seems to be working for now with no error on Volley (aside from authentication error, but that is expected). If the user manually send a request there from a browser, it will redirect to a login page.

Also, if you intend to use token authentication, checkout the devise-token_authentication gem. Devise developers for some reason (which seems to be security) removed the token authentication strategy from devise. This gem is a fork of the token authentication strategy.

Categories
Programming Projects Uncategorized

Introducing, String2Regex

Assalamualaikum everyone. In this post, I’ll show you a (relatively) new project which I’ve created in about a week or two. It seems to be useful for greater good and so I’ve released the code under the MIT license. The code is available here

String2regex is basically a clone of txt2re.com but run entirely on client side and not as full featured. The concept is, given a sample string, generate a regular expression to match that string based on user’s selection of string groups. If you don’t know what is regular expression, you are probably not a programmer and this is effectively useless for you. If you are a programmer but you do not know what is regular expression, then you are missing out. If you know what is a regular expression, check it our here and you’ll understand what does it do. Screnshot

One significance of this application for me is that it is the first (I think) client side application I made that have some kind of automated testing. It is also the my first client side application that is made ground up with some nifty javascript tools such as bower and grunt. Styler and IIUMSchedule both uses grunt for concatenation purpose but not originally. In another word, String2Re is currently the most… what is the word?… decent? proper? … yes, proper web application I’ve ever made right now. 

This is largely due to some automated testing build with it. The testing is not perfect, as it does not test it entirely and it does not test the view, just the controller logic. However the controller logic is quite complicated (not really) so having some test for that reassure me that it will not crash easily. 

Categories
Article Programming Projects

Perbezaan antara Python, Ruby dan PHP.

Assalamualaikum semua, apa khabar, dalam post ini, saya akan mencabar diri saya untuk memperjelaskan perbezaan antara Python, Ruby dan PHP dalam kontext pengatucaraan laman sesawang. Cabaran sebenar saya dalam post ini sebenarnya adalah menggunakan bahasa melayu sebanyak yang mungkin. Sesuatu yang sukar dilakukan memandangkan ini adalah bidang perkomputeran yang mana kebanyakan dokumentasi adalah dalam bahasa Inggeris.