by Bozho | Oct 13, 2011 | Aggregated, Developer tips
Every now and then some OOP purist comes and tells us that getters and setters are evil, because they break encapsulation. And you should never, ever use getters and setters because this is a sign of a bad design and leads to maintainability nightmares. Well, don’t worry, because those people are wrong. Not completely wrong of course, because getters and setters can break encapsulation, but in the usual scenario for regular business projects they don’t. What is the purpose of encapsulation? First, to hide how exactly an object performs its job. And to protect the internal data of an object, so that no external object can violate its state space. In other words, only the object knows which combination of field values is valid and which isn’t. Exposing fields to the outside world can leave the object in inconsistent state. For example what if you could change the backing array in an ArrayList, without setting the size field? The ArrayList instance will be inconsistent and will be violating its contract. So no getter and setter for the array list internal array. But the majority of objects for which people generate getters and setters are simple data holders. They don’t have any rules to enforce on their state, the state space consists of all possible combinations of values, and furthermore – there is nothing they can do with that data. And before you call me “anemic”, it doesn’t matter if you are doing “real OOP” with domain-driven design, where you have business logic & state in the same object, or you are doing fat service layer + anemic objects. Why...
by Bozho | Oct 10, 2011 | Aggregated, Developer tips
I decided that I can make a separate java client library for Google+ (since I was a bit unhappy with what Google have provided for Java developers: no maven dependency, not quite easy to use, not getting updated with the API latest additions, example project using jsp scriptlets). The project is (not too creatively) called “google-plus-java-api” and can be found (including a “getting started” guide) on google code. I am already using it in production for some simple G+ features in my startup, and so I will be updating it whenever Google add more methods, or change something (which I hope won’t happen too often) The project home page shows a sample code to get started. The It’s very similar to other REST API clients like twitter4j, linkedin4j, restfb, other spring social clients. The idea is to be simple and straightforward to use. It has a couple of dependencies, so here are few notes trying to justify them: the library is based on spring-social. It provides a good OAuth2 support (although I had to make some customizations in order to support refresh tokens), and a RestTemplate to simplify rest invocations. The downside is that it fetches some more spring dependencies – spring-web, spring-core, spring-beans and spring-context. This may be problematic for android users, but in general spring-social runs fine on android Jackson is used for JSON deserialization. I’ve seen benchmarks hinting that Jackson is the fastest out there, but either way it is widely adopted and working. It seems to also be working on android. In fact, you can use any json provider as long as you implement a...
by Bozho | Sep 28, 2011 | Aggregated, Developer tips
A standard use-case – you need an entity listener in order to execute some code on every update/insert/delete. For auditing, for example. But things are not straightforward if you need spring dependencies in your listeners and you are using JPA. First of all, the JPA-only listeners are insufficient – you can annotate a method with @PreUpdate, but the most you can get as context is the entity it is about (documentation). But you may need the old values. Or the extracted ID of the entity. Or other metadata. All of that is not supported by JPA. So you need to implement hibernate interfaces like PreDeleteEventListener, PreUpdateEventListener, PostInsertEventListener, etc. and get their XEvent objects. But you can’t easily have these listeners both spring-managed and registered if you are using JPA. You can list them as class names in some hibernate-specific property in persistence.xml, but that way hibernate will instantiate them. Below is the tweaks you need to make in order to get this working: First, extend the persistence provider: public class HibernateExtendedPersistenceProvider extends HibernatePersistence { private PostInsertEventListener[] postInsertEventListeners; private PreUpdateEventListener[] preUpdateEventListeners; private PreDeleteEventListener[] preDeleteEventListeners; @SuppressWarnings("rawtypes") @Override public EntityManagerFactory createEntityManagerFactory(String persistenceUnitName, Map properties) { Ejb3Configuration cfg = new Ejb3Configuration(); setupConfiguration(cfg); Ejb3Configuration configured = cfg.configure( persistenceUnitName, properties ); return configured != null ? configured.buildEntityManagerFactory() : null; } @SuppressWarnings("rawtypes") @Override public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map properties) { Ejb3Configuration cfg = new Ejb3Configuration(); setupConfiguration(cfg); Ejb3Configuration configured = cfg.configure( info, properties ); return configured != null ? configured.buildEntityManagerFactory() : null; } private void setupConfiguration(Ejb3Configuration cfg) { cfg.getEventListeners().setPostInsertEventListeners(postInsertEventListeners); cfg.getEventListeners().setPreDeleteEventListeners(preDeleteEventListeners); cfg.getEventListeners().setPreUpdateEventListeners(preUpdateEventListeners); //TODO if others are needed - add them } public void setPostInsertEventListeners(PostInsertEventListener[] postInsertEventListeners) { this.postInsertEventListeners =...
by Bozho | Sep 22, 2011 | Aggregated, Developer tips
The other day I realized that my Tomcat is using chunked Transfer-Encoding (HTTP 1.1) by default. I don’t know about other servers/containers/frameworks/languages, but it is not uncommon to send pages in chunks – facebook, for example, does it. What “chunked” means is that the server sends pieces of the page that it has already prepared, so that the browser can render them, while the server processes the next chunks. In JSP (and likely in many other view technologies) there is a buffer – whenever the buffer is filled, it is flushed to the client. This means that all headers are sent, together with the first chunk of information (i.e. the contents of the buffer). But there’s one caveat – what happens if an error occurs when the server processes the 2nd (or any subsequent) chunk? You may expect your server to send the error page to the browser, but it can’t work that way: you can’t redirect (send a Location header), because the headers and the response status were already sent. (You can’t, and of course the server can’t) you can’t do server-side redirect (forward), because the new page will have to be rendered after the part that is already sent – it will look ugly for sure I wondered what to do, and asked this question on stackoverflow. Obviously, there is no good way out of the situation. What I did is send this snippet to the browser which then redirects to the error page: </script><script>window.href.location="errorPage"</script> How this is done in JSP in particular: , and redirector.jsp contains the above script tags. Why do we start with a...
by Bozho | Sep 19, 2011 | Aggregated, Developer tips
So, Google released an API for Google+. Sort of. It only has three methods – People.get, Activities.list and Activities.get. But let’s assume we can build something with this. Not something useful, but…something. So I decided to implement two features of my startup (http://welshare.com) – a chart with your posts, replies and +1s per day, and a list of your top recent messages. The API looked sufficient. Since I’m using Java, I grabbed the starter java project. First, the jar with the API classes (+ the ones generated from json) are in a jar that is not available in maven. It is available only in the example project. And the example uses jsp scriptlets. OK, fine. Then I had to authenticate. OAuth2 looks simple, but the classes in the standard google-api-client jar look suspicious. Lots of direct field access (deprecated now), some duplicating fields. OK, this is not the only OAuth2 implementation, so I used the one of spring-social. Worked fine. So, now I have an access token, a refresh token. I implemented the charts and top messages features rather quickly, tested it with my account, it worked fine, and I deployed it. But then other people tried the features and it wasn’t quite working for them – nothing in the “top messages”, and no +1s on the chart. Why is that? Well, it appears there’s a bug – not in welshare, but in Google+ – when you request user activities and pass the maxResults parameter, the plusoners.totalItems field is always 0. OK, you have a bug in your 3 methods that we waited 3 months for. But that’s beta,...
Recent Comments