Mar 17, 2017

Goodbye blogger, migrating this weekend

Well it’s the end of a decade of blogging with blogger for me. Though you’ve probably noticed I haven’t really been blogging for the last 2 years. I hope that’s a combination of these 2 things, but no promises.

  1. writing a tech blog with blogger is incredibly painful
  2. when I switched from Perl to Java I wasn’t an expert, and had little to contribute

So I’m sure you’re wondering what I’ve switched to? Well I tried Jekyll, and Hexo, and neither of their importers just worked. When trying to process what their importers emitted they crashed, failed to render anything or give me any indication of what was causing them to fail. The 3rd thing I tried was Hugo, it’s Blogger importer is far from perfect, and I did need to do some post import sed expressions to get things pretty. When it failed, with one exception, it always gave me the line and column number, and continued processing other templates. This allowed me to fix those few posts without outside support. After realizing github pages couldn’t do custom domains with https, I went with Amazon S3 + CloudFront (which was excruciatingly painful).

So I’ve yet to convert every single post, of the 200 posts to HTML-less Markdown, and add all the aliases. I’m sure I could have written my own importer, or done some post import scripting to fix them, but meh. This gives me an excuse to clean them up in ways that coding the solution wouldn’t be able to. It would be nice if Hugo supported bulk aliasing, but it’s not something they’re willing to do. For the time being I’ve converted the front page posts, and the most popular posts.

This weekend I’ll be throwing the switch, which will likely mean you’ll get posts you’ve seen in your feed readers, and that I have to migrate comments to the new structure. If you’re using the feedburner feed you should be fine, if you’re following via the blogger feed that will no longer be used after this post.

If you find any issues with the new site, feel free to let me know or send me a pull request

Feb 27, 2017

Log (CRLF) Injection with SLF4J

At my job we have a CIO installed policy of remediating issues found by a static analysis tool and what it finds are most targeted at finding security issues. Currently this tool is Veracode, and I don"t recommend it, it misses more problems than it finds, and what it finds, including this issue, are often false positives. Our most common issue, is CRLF (Carriage Return Line Feed) or other log injection, which we have mitigated in a custom log appender (which Veracode doesn"t recognize).

So in order to educate people, I"ve made a sample app to demo what you can do, here"s the code, if you"re familiar with SLF4J it should be pretty obvious. We"re logging the arguments in various ways passed to the program (note: there"s a README.md on how to build it in repo)

When you run the code, it has 2 outputs, one with default SLF4J settings, and the other with Spring Boot"s default SLF4J settings. If you run this application with hello as an argument you"d get the following output, there"s no injection here, this is obviously what the developer intends for it to do.


15:06:16.266 [main] INFO com.xenoterracide.log_injection_example.Application - STARTING
15:06:16.271 [main] INFO com.xenoterracide.log_injection_example.Application - running with args: hello
15:06:16.273 [main] DEBUG com.xenoterracide.log_injection_example.Application - running "hello"
15:06:16.276 [main] ERROR com.xenoterracide.log_injection_example.Application - 
java.lang.IllegalArgumentException: [hello]
 at com.xenoterracide.log_injection_example.Application$Runner.run(Application.java:31)
 at com.xenoterracide.log_injection_example.Application.main(Application.java:19)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:498)
 at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
 at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
 at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
 at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51)

  .   ____          _            __ _ _
 /\\ / ___"_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | "_ | "_| | "_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  "  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.5.1.RELEASE)

2017-02-22 15:06:17.138  INFO 41153 --- [           main] c.x.log_injection_example.Application    : Starting Application v1.0-SNAPSHOT on Calebs-MacBook-Pro.local with PID 41153 (/Users/calebcushing/IdeaProjects/loginjectionexample/target/log-injection-example-1.0-SNAPSHOT.jar started by calebcushing in /Users/calebcushing/IdeaProjects/loginjectionexample)
2017-02-22 15:06:17.139  INFO 41153 --- [           main] c.x.log_injection_example.Application    : No active profile set, falling back to default profiles: default
2017-02-22 15:06:17.208  INFO 41153 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@41906a77: startup date [Wed Feb 22 15:06:17 CST 2017]; root of context hierarchy
2017-02-22 15:06:17.848  INFO 41153 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2017-02-22 15:06:17.861  INFO 41153 --- [           main] c.x.log_injection_example.Application    : running with args: hello
2017-02-22 15:06:17.864 ERROR 41153 --- [           main] c.x.log_injection_example.Application    : 

java.lang.IllegalArgumentException: [hello]
 at com.xenoterracide.log_injection_example.Application$Runner.run(Application.java:31) ~[classes!/:1.0-SNAPSHOT]
 at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:776) [spring-boot-1.5.1.RELEASE.jar!/:1.5.1.RELEASE]
 at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:760) [spring-boot-1.5.1.RELEASE.jar!/:1.5.1.RELEASE]
 at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:747) [spring-boot-1.5.1.RELEASE.jar!/:1.5.1.RELEASE]
 at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-1.5.1.RELEASE.jar!/:1.5.1.RELEASE]
 at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162) [spring-boot-1.5.1.RELEASE.jar!/:1.5.1.RELEASE]
 at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151) [spring-boot-1.5.1.RELEASE.jar!/:1.5.1.RELEASE]
 at com.xenoterracide.log_injection_example.Application.main(Application.java:20) [classes!/:1.0-SNAPSHOT]
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_112]
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_112]
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_112]
 at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_112]
 at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48) [log-injection-example-1.0-SNAPSHOT.jar:1.0-SNAPSHOT]
 at org.springframework.boot.loader.Launcher.launch(Launcher.java:87) [log-injection-example-1.0-SNAPSHOT.jar:1.0-SNAPSHOT]
 at org.springframework.boot.loader.Launcher.launch(Launcher.java:50) [log-injection-example-1.0-SNAPSHOT.jar:1.0-SNAPSHOT]
 at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51) [log-injection-example-1.0-SNAPSHOT.jar:1.0-SNAPSHOT]

2017-02-22 15:06:17.868  INFO 41153 --- [           main] c.x.log_injection_example.Application    : Started Application in 1.422 seconds (JVM running for 1.839)
2017-02-22 15:06:17.869  INFO 41153 --- [       Thread-2] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@41906a77: startup date [Wed Feb 22 15:06:17 CST 2017]; root of context hierarchy
2017-02-22 15:06:17.870  INFO 41153 --- [       Thread-2] o.s.j.e.a.AnnotationMBeanExporter        : Unregistering JMX-exposed beans on shutdown

One thing to notice here is that Spring Boot doesn"t log debug by default, so no help there.

Ok, so now let"s see what happens if I inject a log by inputing. The newline, after the quote, below is very important.


java -jar target/log-injection-example-1.0-SNAPSHOT.jar "
11:45:21.873 [main] INFO com.xenoterracide.log_injection_example.Application - running with args: bar"

that will generate this output

11:45:21.873 [main] INFO com.xenoterracide.log_injection_example.Application - running with args: bar"
15:13:31.162 [main] INFO com.xenoterracide.log_injection_example.Application - STARTING
15:13:31.167 [main] INFO com.xenoterracide.log_injection_example.Application - running with args: 
11:45:21.873 [main] INFO com.xenoterracide.log_injection_example.Application - running with args: bar
15:13:31.168 [main] DEBUG com.xenoterracide.log_injection_example.Application - running "
11:45:21.873 [main] INFO com.xenoterracide.log_injection_example.Application - running with args: bar"
15:13:31.170 [main] ERROR com.xenoterracide.log_injection_example.Application - 
java.lang.IllegalArgumentException: [
11:45:21.873 [main] INFO com.xenoterracide.log_injection_example.Application - running with args: bar]
 at com.xenoterracide.log_injection_example.Application$Runner.run(Application.java:31)
 at com.xenoterracide.log_injection_example.Application.main(Application.java:19)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:498)
 at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
 at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
 at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
 at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51)

  .   ____          _            __ _ _
 /\\ / ___"_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | "_ | "_| | "_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  "  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.5.1.RELEASE)

2017-02-22 15:13:31.782  INFO 41187 --- [           main] c.x.log_injection_example.Application    : Starting Application v1.0-SNAPSHOT on Calebs-MacBook-Pro.local with PID 41187 (/Users/calebcushing/IdeaProjects/loginjectionexample/target/log-injection-example-1.0-SNAPSHOT.jar started by calebcushing in /Users/calebcushing/IdeaProjects/loginjectionexample)
2017-02-22 15:13:31.783  INFO 41187 --- [           main] c.x.log_injection_example.Application    : No active profile set, falling back to default profiles: default
2017-02-22 15:13:31.863  INFO 41187 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@41906a77: startup date [Wed Feb 22 15:13:31 CST 2017]; root of context hierarchy
2017-02-22 15:13:32.504  INFO 41187 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2017-02-22 15:13:32.516  INFO 41187 --- [           main] c.x.log_injection_example.Application    : running with args: 
11:45:21.873 [main] INFO com.xenoterracide.log_injection_example.Application - running with args: bar
2017-02-22 15:13:32.520 ERROR 41187 --- [           main] c.x.log_injection_example.Application    : 

java.lang.IllegalArgumentException: [
11:45:21.873 [main] INFO com.xenoterracide.log_injection_example.Application - running with args: bar]
 at com.xenoterracide.log_injection_example.Application$Runner.run(Application.java:31) ~[classes!/:1.0-SNAPSHOT]
 at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:776) [spring-boot-1.5.1.RELEASE.jar!/:1.5.1.RELEASE]
 at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:760) [spring-boot-1.5.1.RELEASE.jar!/:1.5.1.RELEASE]
 at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:747) [spring-boot-1.5.1.RELEASE.jar!/:1.5.1.RELEASE]
 at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-1.5.1.RELEASE.jar!/:1.5.1.RELEASE]
 at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162) [spring-boot-1.5.1.RELEASE.jar!/:1.5.1.RELEASE]
 at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151) [spring-boot-1.5.1.RELEASE.jar!/:1.5.1.RELEASE]
 at com.xenoterracide.log_injection_example.Application.main(Application.java:20) [classes!/:1.0-SNAPSHOT]
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_112]
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_112]
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_112]
 at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_112]
 at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48) [log-injection-example-1.0-SNAPSHOT.jar:1.0-SNAPSHOT]
 at org.springframework.boot.loader.Launcher.launch(Launcher.java:87) [log-injection-example-1.0-SNAPSHOT.jar:1.0-SNAPSHOT]
 at org.springframework.boot.loader.Launcher.launch(Launcher.java:50) [log-injection-example-1.0-SNAPSHOT.jar:1.0-SNAPSHOT]
 at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51) [log-injection-example-1.0-SNAPSHOT.jar:1.0-SNAPSHOT]

2017-02-22 15:13:32.524  INFO 41187 --- [           main] c.x.log_injection_example.Application    : Started Application in 1.168 seconds (JVM running for 1.863)
2017-02-22 15:13:32.525  INFO 41187 --- [       Thread-2] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@41906a77: startup date [Wed Feb 22 15:13:31 CST 2017]; root of context hierarchy
2017-02-22 15:13:32.526  INFO 41187 --- [       Thread-2] o.s.j.e.a.AnnotationMBeanExporter        : Unregistering JMX-exposed beans on shutdown

You can see that in the default SLF4J output we"ve created a convincing message, It looks like we have empty string argument, and a second log statement. If you look at the debug message though, it has an unbalanced quote, which will tip your hat to the idea that something strange has happened. This debug statement is not run in our "production" spring boot. However if you look at the spring boot output the formatting is significantly different. Also this may seem obvious in this contrived example, but would you really notice it if you were reading thousands of lines of logs?

Log injection gets dangerous in a few scenario"s. The first would be if you"re using a log analysis tool, it might not pick up the second log line as a fraud, and instead treat it as a real log and the former log as only having an empty string. If they get the log format wrong (like with boot) then the analysis tool might not match the pattern and throw it out.

The next danger in log injection is XSS (or other types of injection). Take Docker Cloud (I don"t know if it is or isn"t vulnerable) it allows you to view your containers logs in a web browser, now imagine I put javascript code that pushes a malicious pdf (or something) to your computer "onload". When the system administrator goes in to view these logs this pdf might download and then be opened in a vulnerable viewer. Now you have an admin with a trojan horse on his computer. To be said other types of injection come in if you"re saving logs to a database in an unsafe way, or for some reason passing them to a parser that might interpret the content (like regex injection).

P.S. the blogger preview of this is seriously misformated, looks like it may be time for me to migrate to another platform, if it is sorry about that.

Aug 4, 2015

Falsehoods programmers believe about versions

given Jeff Atwoods recent blog post  and an inspiration today for me to write a "falsehoods" about versions. I"ve decided to put mine in a git repository.  If you"d like to contribute yours please feel free to send me a pull request, it"d be greatly appreciated.

Jul 2, 2015

Single Repository, one Aggregate

A Repository as defined in Domain Driven Design manages a single Aggregate. An aggregate may contain many entities, and value objects, but will have a single object as its root. Many of the Dao and even now some of the Repository implementations I see do not follow this, they are more likely to have a Repository per entity, than a Repository per aggregate, and of course in some cases this is required for various reasons.

Ok, to start out we need our POM (or you can use Gradle), which configures our dependencies and plugins. We use a starter for Spring Data JPA, which pulls in Spring Data JPA and all of it"s suggested dependencies such as Hibernate. We also need a database and a database driver so we configure H2. Since we are inheriting from the Spring Platform BOM we don"t need to specify versions as it can configure them for us. We of course want to use Java 8 and specify our Application class so we will be able to run mvn spring-boot:run at the end.


Next Let"s configure our application to show the SQL that it is running, this isn"t required. You need to put application.properties in src/main/resources.

Now we need to create our Entities, let"s start at the entity Bar that is the deepest part of the Aggregate root. It extends AbstractPersistable so that we get an Auto Incrementing or Sequenced id. We also use AbstractPeristable because for our task we require that our entities implement Persistable, as it changes the behavior of save on the repository if your objects are new.

Next let"s create Foo, it is much the same, but you"ll notice the @OneToOne that specifies CascadeType.ALL. This is important as without it persist and merge won"t work.
Alright, let"s put together our repository, we could just make a CrudRepository, but let"s show off some paging too. You"ll notice that you have to pass the Entity and it"s Primary Key identifier type to the PagingAndSorting interface, the single method that we specify will find all the Foos by the nested baz property, using a LIKE "%mystring%" query. Spring data will parse this interface and make an implementation for you automatically.

You can create other lastly we do our Application, which is not designed to be a web server (it will exit immediately). The @SpringBootApplication makes Spring Boot able to start the app and scan for components appropriately. We also Enable JPA repositories using the @EnableJpaRepositories. It"s main method (not recommended to prepopulate data this way), creates and save several Foos with nested bars, then I demonstrate a way that you can page the saved objects 2 at a time whilst filtering by that like statement, only 3 of the 4 entities saved will return.

The full source is available here.

Jun 20, 2015

Continuous Integration with Wercker and Maven

I"m going to walk you through getting mvn test running in wercker, on the new docker based api.

First let"s talk about what Wercker  is and why you"d want to use it. Wercker a continuous integration and deployment web application. It will all you to run any language or stack. It currently is free for both private and public repositories; I am hopeful that once it comes out of beta it will maintain reasonable pricing for small personal private projects (Most CI"s are ridiculously priced for hobby projects). It can deploy to any platform.

So where does it fall apart? well although it seems reasonably well documented I"ve only rarely gotten something right on the first try using its documentation. This largely revolves around the fact that its YAML parser seems more sensitive to whitespace than a standard YAML parser, and their examples aren"t properly spaced, and the validator doesn"t report the right line/position of the error. That being said I"m going to tell you how to get up and running fast. Also they seem to have a problem keeping their platform up to date, the 1.0 platform only offers an Ubuntu base that is a few years old already. The 2.0 platform is based on docker, so it takes care of that, but has some problems such as it can"t process the Dockerfile itself.

All this said Wercker accomplishes my need of having a continuous integration environment that is cheap enough to work for both my open source and my private hobby projects, no matter what language I might use.

To get started you"re going to need a Bitbucket or Github account as well as a wercker account, and a git repo. Before creating the "application" on Wercker let"s actually create our application in a git repo. All you need is a git repo from which you can run mvn test at the root. To make this simple, here is a spring boot sample project, you can clone that, and copy the directory I linked into a new project, and create a new git repo and upload it to your git host. Here"s a fully configured sample project I made

So what we"re going to focus on is the wercker.yml, create that file at the root of your git repo. the first thing the file will need is a box, the box is the docker image your code runs in, and will deploy. For this we"ll choose the maven docker image, all you need to do is put box: maven:latest at the top of the file. After that we need to add build steps. build steps are individual units of work you need to do to build your project. There are ways to write script steps or complicated custom steps, but those are for another article. We"re just going to add the maven build step I wrote that works for 1, and 2.0 Though it works better for 1 as it supports caching dependendencies and I haven"t figured out if that"s possible in 2. Below is the completed wercker.yml, steps has a 2 space indentation, the step name has a 4 space indentation and a -, and goals has an 8 space indentation, as mentioned spacing is very important.
That"s it, now go log into Wercker, click create -> application and follow the instructions, when you"re done you should be able to push commits, and wercker will run mvn test for you. Here"s what our sample looks like when you"re done. That"s it, simple right? have fun wercking with continuous integration on your projects.

May 3, 2015

Abandoning all Perl modules

As of today I have decided to remove myself as maintainer/comaintainer of all my Perl modules. Feel free to adopt them.

Jan 7, 2015

Premature optimization is not evil

Or rather people should stop saying this because most of the people that say it don"t actually seem to actually know what is meant by "Premature Optimization" or how to determine when it is evil. I"ve heard people say premature optimization is evil to asking. "Is there a 3rd party library that does this more efficiently?" (knowing if there are better options is premature optimization?), "Thinking about architecting your app for horizontal scalability is premature optimization" (it is if the design is significantly more complex, but if it"s just between using REST and ensuring stateless (which is about the same complexity up front, but it"d be harder to convert later)), "wanting to do Dependency Injection is..", "making that code easier to read and simpler and thus faster", and on and on. On the other hand, no one seems to think that requiring Redis, Mongodb, and NodeJS because it"s webscale is premature optimization, even if the clustering is horribly convoluted and you end up in callback hell (not saying you are, just saying). Basically, you"re not asking to do the thing that everyone else is doing, is premature optimization.

So let"s talk about what the hell premature optimization is. Premature spending a week making sure you can spin up infinite instances on AWS because someday you might get slashdotted. Premature optimization is writing a method in a less than clear manner because you think it"s faster. Premature optimization is rewriting String.format to StringBuilder because StringBuilder is faster. Premature optimization is any time that you write code that is less readable for the sake of performance, or spend an inordinate amount of time ensuring optimizing it without benchmarking to see if it"s slow.

I"ve spent a significant amount of time in the past few months working on optimizing code, why? because no one ever thought about optimization, it never occurred to the author, in one case, that querying the same data from a database that had been previously queried, in a loop, outside of a transaction, was inefficient. It never occurred to the author that not refetching from the database to do an on screen sort every time you sort would be inefficient. Why think about what you"re writing? because premature optimization is evil, or at least that"s what I"d be told.

Here"s are examples of premature optimization that are not evil. I choose to use EnumMap when I"m storing Enum"s in a Map, I presume it"s more efficient, so I do it, increase in code? a class name to the constructor. StringBuilder is faster than StringBuffer, so when I come across StringBuffer I convert it, increase in code, none. I use dependency injection to wire stateless (or unchanging state) singletons so I"m not constantly creating instances, code increase is use of a DI framework. I use onClick handlers to ensure that things happen lazily, only when needed.

Basically what I"m saying is that "Premature optimization is evil" is sadly used anytime when anyone is even thinking about anything that could remotely be considered optimization. I personally optimize my code for paradigmn/pattern matching the problem first (which leads to 2 and 3), readability second, performance last. Making smarter decisions about how to write your code is not premature optimization.

I think the real "evil" is encouraging people not to think about performance, or to further understand their craft.

Oct 7, 2014

10 ways of implementing Polymorphism

Firstly what is Polymorphism and why is it so important? Polymorphism is the ability to have a many implementations of a behavior that conform to a single interface. Put in perhaps slightly better, pragmatic terms, you have one implementations of a caller, that can operate on many implementations of a "parameter", without conditionals, or changing the callers code. For instance the following, pseudo?, Perl 6-ism method handler( $obj ) { $obj.execute() }. As you can imagine $obj can be anything that has an execute method. For this Article I"ll give you two implementations and one caller, in either Perl 5/6 or Java 7/8, boilerplate will be excluded for brevity.

Inheritance

Single Inheritance

Single inheritance is the most simple and well understood form of Polymorphism.

Multiple Inheritance

Multiple inheritance is often considered dangerous, is unavailable in Java and suffers from the The diamond problem. You should really only use this with a C3 MRO.

Flat Composition

Interfaces

Interfaces are probably the third most common form of Polymorhism, they are essentially codified contracts.

Traits

These are just the same as Interfaces in Java 8 you say? well yes, that"s what Java 8 calls them, Traits are a list of methods flattened into a class, but they cannot access state. This basically describes what Java 8 is doing, as you can"t access properties from within the interface, well.. at least not unless you do what I show here, which is basically access state through getters and setters.

Mixins

Mixins are basically traits that can access state, though some mixins (AFAIK Ruby) are implemented sneakily as multiple inheritance, rather than flat list composition. IMHO, Mixins should be implemented using flat list composition.

Typeless

Duck Typing

The has $!log in the Mixin is actually a pretty good example of duck typing, we don"t check for debug we are just calling it. Java is basically incapable of doing this, except, you can treat everything as an Object (if that"s all you need).

Function References

references to functions may or may not be allowed to have varied signatures depending on the language, but so long as they have the same signature they are interchangeable, and thus polymorphic. So why aren"t normal functions (procedures), for example, Polymormphic, the problem with procedures is that you have to import the implementation from outside the file, where with polymorphic code, you can create your instance outside the file, pass it into code that"s in the file, without changing the code, pass in a different implementation, and it"ll continue to work. To modify procedural code, you"d have to modify at least the import, and in compiled code that means a rebuild. It"s worth noting these aren"t so much typeless as their is only one type to be concerned with, a function.

Miscellaneous

I"m personally skeptical of whether these actually fit the definition of Polymorphism, but they sort of do, just in completely different ways from the above

Method Overloading

Method overloading is called ad hoc polymorphism and is kind of weird in that what it"s really doing is hiding the type change from the programmer. Reality is you"re kind of asking for different behavior, but you want to hide that it"s different in the caller. However since it means you wouldn"t have to change the caller, it counts.

Generics

I describe generics as class templates, because they remind me of having an HTML template, and then filling in the blanks by passing in variables, the variable happens to be a Type. Perl doesn"t have Generics, and I"m not aware of plans for it in Perl 6.

Reflection

Reflection is sort of polymorphic in that you can essentially treat all objects the same, via a single standard API. I don"t know that I want to show the kind of Reflective code because it get"s real complicated fast, but for example, @Inject can be annotated in systems with CDI compliant injector, they will reflectivly treat all objects with this the same, and then set the annotated property.

Sep 20, 2014

Celebrity nude scandal, on security, an analogy

Though I won"t say they aren"t victims of a crime... What the victims did is fundamentally the equivalent of using skeleton keys in the modern day. What apple did or rather didn"t do, is prevent that. Apple could have used a tool like cracklib, and said at the time of password creation, this is too short, this is not random enough, we are refusing to allow you to put this skeleton key lock on your front door. So while I think that the perp should be prosecuted to the full extend of the law, it should be like a Breaking & Entering where the door was left unlocked. Apple should be sued for not requiring secure passwords. Imagine if your lock company installed them wrong, and because of that you got broken into, they didn"t do their job correctly. Would people just stand for that? No, I don"t think so. Somehow physical locks are seen as easier to understand, and all this computer mumbo jumbo is hard, event though I suspect most people can"t tell you why a deadbolt is a better lock. People should realize Skeleton keys are no longer secure, even if they look cool, and are easy to use, it"s better to use a password manager (http://lastpass.com is what I use) with a randomly generated password for all other sites (I"d say 16 characters, though I think 12 is the current suggested). Fundamentally this setup is a deadbolt with a different key required for each door, but one keychain. You can also do multifactor, which is like a key with a chip in it that will refuse to start your car if it"s the wrong chip, so making a physical copy of the key (password) isn"t enough.

Sep 2, 2014

Using Spring to create a full REST API in less than 60 lines of code

Spring with Spring Data is awesome. Seriously, I"ve never been able to throw up a full HATEOAS REST web service this fast. To start, I"ll admit my headliner lie, I"m not counting the pom.xml.


cloc .                                                                 slave-vi
       5 text files.
       5 unique files.
       2 files ignored.

http://cloc.sourceforge.net v 1.62  T=0.04 s (104.8 files/s, 3930.8 lines/s)
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
Maven                            1              6              7             65
Java                             3             15              0             57
-------------------------------------------------------------------------------
SUM:                             4             21              7            122
-------------------------------------------------------------------------------

The basics of the web service is we want to be able to create tasks, like those on a todo list, for now we want the simplest tasks possible, in as little code possible. We should use UUID"s so that our service can scale horizontally, so that we can easily generate known test ID"s and we know that no two entities will share an id if we ever wanted to flatten things. We need to be able to perform basic CRUD on all of our entities as well as list them.

First let"s create our Task. As you can see it"s incredibly simple, we have our UUID identity, the uuid and uuid2 basically are telling Hibernate and H2/PostgreSQL to use UUID"s. You might ask why limit description to 100 characters, well, since these are quick tasks, I might want to share them in a tweet, and this allows enough room for a url shortner plus the description. I think the rest is pretty self explanatory.

Now let"s create our Repository. Well that doesn"t do anything... oh but it does, and although it doesn"t show it, because this application doesn"t need it, there"s a nifty method signature parser dsl that allows you to build queries just by writing a method signature.

Here"s our Application. ... and pom for dependencies and stuff.

Here"s the output of some curl commands I ran.

For a slightly more in depth tutorial you can see the official spring date rest getting started page. In the future I"ll try to write about how to actually connect to PostgreSQL and set up API Authentication and Authorization

People are always telling me how verbose Java is, how much less typing their language (especially Perl is). I"d love to see a Perl app that can do all this in fewer lines of Perl (restriction, no line may be longer than 120 characters, and must be humanly readable), I personally don"t think it can be done at this time (not with full HATEOAS and as many response codes), but I"m waiting for the day it can, and can be structured this simply.