by Bozho | Aug 7, 2016 | Aggregated, Opinions
In the past year I’ve taken the position of an adviser in the cabinet of a deputy prime minister and as a result of that I had the option to draft legislation. I’ve been doing that with a colleague, both with strong technical background, and it turned out we are not bad at it. Most of “our” laws passed, including the “open source law”, the electronic identification act, and the e-voting amendments to the election code (we were, of course, helped by legal professionals in the process, much a like a junior dev is helped by a senior one). And law drafting felt to have much in common with programming – as a result “our” laws were succinct, well-structured and “to the point”, covering all use-cases. At first it may sound strange that people not trained in the legal profession would be able to do it at all, but writing laws is actually “legal programming”. Here’s what the two processes have in common: Both rely on a formalized language. Programming languages are stricter, but “legalese” is also quite formalized and certain things are worded normally in a predefined way, in a way there are “keywords”. There is a specification on how to use the formalized language and how it should behave. The “Law for normative acts” is the JLS (Java language specification) for law-drafting- it defines what is allowed, how laws should be structured and how they should refer to each other. It also defines the process of law-making. Laws have a predefined structure, just as a class file, for example. There are sections, articles, references and modification clauses...
by Bozho | Jul 18, 2016 | Aggregated, Developer tips
If you need to have automatic auditing of all database operations and you are using Hibernate…you should use Envers. But if for some reasons you can’t use Envers, you can achieve something similar with hibernate event listeners and spring transaction synchronization. First, start with the event listener. You should capture all insert, update and delete operations. But there’s a tricky bit – if you need to flush the session for any reason, you can’t directly execute that logic with the session that is passed to the event listener. In my case I had to fetch some data, and hibernate started throwing exceptions at me (“id is null”). Multiple sources confirmed that you should not interact with the database in the event listeners. So instead, you should store the events for later processing. And you can register the listener as a spring bean as shown here. @Component public class AuditLogEventListener implements PostUpdateEventListener, PostInsertEventListener, PostDeleteEventListener { @Override public void onPostDelete(PostDeleteEvent event) { AuditedEntity audited = event.getEntity().getClass().getAnnotation(AuditedEntity.class); if (audited != null) { AuditLogServiceData.getHibernateEvents().add(event); } } @Override public void onPostInsert(PostInsertEvent event) { AuditedEntity audited = event.getEntity().getClass().getAnnotation(AuditedEntity.class); if (audited != null) { AuditLogServiceData.getHibernateEvents().add(event); } } @Override public void onPostUpdate(PostUpdateEvent event) { AuditedEntity audited = event.getEntity().getClass().getAnnotation(AuditedEntity.class); if (audited != null) { AuditLogServiceData.getHibernateEvents().add(event); } } @Override public boolean requiresPostCommitHanding(EntityPersister persister) { return true; // Envers sets this to true only if the entity is versioned. So figure out for yourself if that's needed } } Notice the AuditedEntity – it is a custom marker annotation (retention=runtime, target=type) that you can put ontop of your entities. To be honest, I didn’t fully follow how Envers does the...
by Bozho | Jul 15, 2016 | Aggregated, Developer tips
Hibernate offers event listeners as part of its SPI. You can hook your listeners to a number of events, including pre-insert, post-insert, pre-delete, flush, etc. But sometimes in these listeners you want to use spring dependencies. I’ve written previously on how to do that, but hibernate has been upgraded and now there’s a better way (and the old way isn’t working in the latest versions because of missing classes). This time it’s simpler. You just need a bean that looks like this: @Component public class HibernateListenerConfigurer { @PersistenceUnit private EntityManagerFactory emf; @Inject private YourEventListener listener; @PostConstruct protected void init() { SessionFactoryImpl sessionFactory = emf.unwrap(SessionFactoryImpl.class); EventListenerRegistry registry = sessionFactory.getServiceRegistry().getService(EventListenerRegistry.class); registry.getEventListenerGroup(EventType.POST_INSERT).appendListener(listener); registry.getEventListenerGroup(EventType.POST_UPDATE).appendListener(listener); registry.getEventListenerGroup(EventType.POST_DELETE).appendListener(listener); } } It is similar to this stackoverflow answer, which however won’t work because it also relies on deprecated calsses. You can also inject a List of listeners (though they don’t share a common interface, you can define your own). As pointed out in the SO answer, you can’t store new entities in the listener, though, so it’s no use injecting a DAO, for example. But it may come handy to process information that does not rely on the current...
by Bozho | Jun 26, 2016 | Aggregated, Developer tips
It sounds like something you’d never need, but sometimes, when you distribute end-user software, you may need to install a java program as a Windows service. I had to do it because I developed a tool for civil servants to automatically convert and push their Excel files to the opendata portal of my country. The tool has to run periodically, so it’s a prime candidate for a service (which would make the upload possible even if the civil servant forgets about this task altogether, and besides, repetitive manual upload is a waste of time). Even though there are numerous posts and stackoverflow answers on the topic, it still took me a lot of time because of minor caveats and one important prerequisite that few people seemed to have – having a bundled JRE, so that nobody has to download and install a JRE (would complicate the installation process unnecessarily, and the target audience is not necessarily tech-savvy). So, with maven project with jar packaging, I first thought of packaging an exe (with launch4j) and then registering it as a service. The problem with that is that the java program uses a scheduled executor, so it never exits, which makes starting it as a process impossible. So I had to “daemonize” it, using commons-daemon procrun. Before doing that, I had to assemble every component needed into a single target folder – the fat jar (including all dependencies), the JRE, the commons-daemon binaries, and the config file. You can see the full maven file here. The relevant bits are (where ${installer.dir} is ${project.basedir}/target/installer}): <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration>...
by Bozho | Jun 17, 2016 | Aggregated, Developer tips, Opinions
There are many ways to work with git. The workflows vary depending on the size of the team, organization, and on the way of working – is it distributed, is it sprint-based, is it a company, or an open-source project, where a maintainer approves pull requests. You can use vanilla-git, you can use GitHub, BitBucket, GitLab, Stash. And then on the client side you can use the command line, IDE integration, or stand-alone clients like SourceTree. The workflows differ mostly in the way you organize you branches and the way you merge them. Do you branch off branches? Do you branch off other people’s branches, which are work-in-progress. Do you push or stay local? Do you use it like SVN (perfectly fine for a single developer on a pet project), or you delve into more “arcane” features like --force-with-lease. This is all decided by each team, but I’d like to focus on one very debated topic – rebasing vs merging. While you can get tons of results discussing rebasing vs merging, including the official git documentation, it has become more of a philosophical debate, rather than a practical one. I recently asked a practical question about a rebase workflow. In short, by default rebasing seems not to favour pushing stuff to the central repo. If you do that before rebasing, you’d always need to force-push. And force-pushing may make it very hard for people that are based on your branch. Two questions that you are already asking: Why do you need to push if something isn’t ready? Isn’t it the point of the “D” in “DVCS” to be able...
Recent Comments