Just extraordinary
blog van Paul Hildebrand
blog van Paul Hildebrand
sep 26th
Today I was trying out JavaFX 2.0 beta which is soon to be released as final. I tried to make a small game where you can fly around a small plane. This is not to hard, you just take the image of a plane taken from the top and make it rotate by listening to key events for left and right and of course a key event to make it go forward.
But when I made a KeyPressedEventHandler I noticed that it would only handle one key at a time. But for a game you need multiple keys handled simultaneously. For instance turning a plane to the left (Key.LEFT) while throttling (Key.UP). When multiple keys are pressed at the same time the KeyPressedEvent is triggered for all keys but only an event for the last pressed key will be triggered continuously. Luckily I found out that the KeyReleasedEvent is always triggered. This gave me the idea to buffer all the pressed keys, and remove each key from the buffer when a release of the given key was done.
The code below creates a new event handler which buffers the pressed keys in a EnumSet.
- A key is added to the set when the KeyPressedEvent is triggered.
- A key is removed from the set when the KeyReleasedEvent is triggered.
import java.util.EnumSet;
import java.util.Set;
import javafx.event.EventHandler;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
/**
*
* @author Paul
*/
public class MultiplePressedKeysEventHandler implements EventHandler<KeyEvent> {
private final Set<KeyCode> buffer = EnumSet.noneOf(KeyCode.class);
private final MultiKeyEvent multiKeyEvent = new MultiKeyEvent();
private final MultiKeyEventHandler multiKeyEventHandler;
public MultiplePressedKeysEventHandler(final MultiKeyEventHandler handler) {
this.multiKeyEventHandler = handler;
}
public void handle(final KeyEvent event) {
final KeyCode code = event.getCode();
if (KeyEvent.KEY_PRESSED.equals(event.getEventType())) {
buffer.add(code);
multiKeyEventHandler.handle(multiKeyEvent);
} else if (KeyEvent.KEY_RELEASED.equals(event.getEventType())) {
buffer.remove(code);
}
event.consume();
}
public interface MultiKeyEventHandler {
void handle(final MultiKeyEvent event);
}
public class MultiKeyEvent {
public boolean isPressed(final KeyCode key) {
return buffer.contains(key);
}
}
}
This is an example how to use the new MultiplePressedKeysEventHandler. Notice that you will have to add this event handler to both the “setOnKeyPressed” and “setOnKeyReleased” method.
The MultiKeyEvent gives you access to a method “isPressed” which you can use to check if the given key is pressed.
private void initKeyEventHandler() {
final MultiplePressedKeysEventHandler keyHandler =
new MultiplePressedKeysEventHandler(new MultiKeyEventHandler() {
public void handle(MultiKeyEvent ke) {
if (ke.isPressed(KeyCode.POWER) || ke.isPressed(KeyCode.X)) {
Platform.exit();
}
if (ke.isPressed(KeyCode.LEFT) || ke.isPressed(KeyCode.A)) {
rotation -= 2d;
}
if (ke.isPressed(KeyCode.RIGHT) || ke.isPressed(KeyCode.D)) {
rotation += 2d;
}
if (ke.isPressed(KeyCode.UP) || ke.isPressed(KeyCode.W)) {
speed += 0.1d;
}
if (ke.isPressed(KeyCode.DOWN) || ke.isPressed(KeyCode.S)) {
speed -= 0.1d;
}
}
});
imageView.setFocusTraversable(true);
imageView.setOnKeyPressed(keyHandler);
imageView.setOnKeyReleased(keyHandler);
}
This peace of code has some rough edges and can be improved in many ways. I hope it gave you an idea or direction how to solve the given problem.
mei 23rd
If you use cobertura for checking your jUnit code coverage, you have probably also encountered the problem that private constructors cannot be covered. All your classes have 100% coverage but your utillity classes with private constructors stick at 90 or 95% (or even less). Those red sections in the cobertura overview annoyed the hell out of me so I did some research and found a solution using Java reflection.
@Test
public void testPrivateConstructor() throws Exception {
Constructor<?>[] cons = MyUtil.class.getDeclaredConstructors();
cons[0].setAccessible(true);
cons[0].newInstance((Object[])null);
}
Just add this test to one of your unit tests and replace “MyUtil” with your class and tada!! your private constructor is covered.
Of course, code coverage is not a measure of quality but you get my point.
apr 19th
It won’t be long or the final version of scala 2.9.0 will be coming out. And one of the new features is “parallel collections”. It’s a really really cool feature and also very easy to use. Just by invoking the par method on a collection you can do all kind of actions like foreach, map, fold, partition etc and convert a sequential collection in a parallel one using the multi-core features of a modern processor.
Example sequential collection:
object SequentialExample extends Application {
(1 to 10).foreach(x => print(" " + x))
}
Output:
1 2 3 4 5 6 7 8 9 10
When you execute this code, it will print 1 to 10 in a sequential manner, like you would expect.
In the parallel example I have only added the “par” method to the collection. The rest is the same.
object ParallelExample extends Application {
(1 to 10).par.foreach(x => print(" " + x))
}
Output:
1 6 7 8 9 10 3 4 5 2
You can see that the numbers in the output are no longer sequential. Because the load of the foreach method has been distributed over multiple cores (in parallel) you can no longer predict the sequence of the numbers.
Thoughts
For small lists with cheap calculations per entry parallel collections are probably overkill and you might introduce more overhead then gaining actually some speed. But with large lists or expensive calculations per entry you probably will see some fantastic performance gains.
Features like this make multi-core programming somewhat more accessible for the general programmer and that’s a big plus because even people who say they understand how to code with threads, the majority actually still doesn’t.
Links
Download scala 2.9.0 RC1
Official Scala documentation of collections
apr 4th
Recently I was wondering whether it was possible to use JPA (Java Persistence API) with Scala. So I did some fiddling around and found out that it is quite easy with Scala (but that’s not a surprise).
I used the following libraries in this example:
- Hibernate 3.5.6.Final (JPA2 implementation)
- Hsqldb 1.8.0.7
- Spring 3.0.5
- Scala 2.8.1
Scala code
First I created an entity class “Customer” with a first and a last name and of course an id.
package nl.paulhildebrand.jpa
import javax.persistence._
import scala.reflect.BeanProperty
@Entity
@Table(name = "customer")
class Customer(f: String, l: String) {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@BeanProperty
var id: Int = _
@BeanProperty
var firstName: String = f
@BeanProperty
var lastName: String = l
def this() = this (null, null)
override def toString = id + " = " + firstName + " " + lastName
}
Because it is an example I kept the entity “Customer” simple. Nice to notice is the @BeanProperty annotation. It dynamically adds a getter and a setter for the given variable. This keeps the code clean and the JPA implementation working. The rest is similar to a Java implementation.
To access the database I created a DAO. But first I needed to define the interface for it. In scala an interface is called a Trait.
package nl.paulhildebrand.jpa
trait CustomerDao {
def save(customer: Customer): Unit
def find(id: Int): Option[Customer]
def getAll: List[Customer]
def getByLastName(lastName : String): List[Customer]
}
As you can see it has some simple method to save and find customers. Lets have a look at the implementation of the trait.
package nl.paulhildebrand.jpa
import org.springframework.beans.factory.annotation._
import org.springframework.stereotype._
import org.springframework.transaction.annotation.{Propagation, Transactional}
import javax.persistence._
import scala.collection.JavaConversions._
@Repository("customerDao")
@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
class CustomerDaoImpl extends CustomerDao {
@Autowired
var entityManager: EntityManager = _
def save(customer: Customer): Unit = customer.id match {
case 0 => entityManager.persist(customer)
case _ => entityManager.merge(customer)
}
def find(id: Int): Option[Customer] = {
Option(entityManager.find(classOf[Customer], id))
}
def getAll: List[Customer] = {
entityManager.createQuery("From Customer", classOf[Customer]).getResultList.toList
}
def getByLastName(lastName : String): List[Customer] = {
entityManager.createQuery("From Customer Where lastName = :lastName", classOf[Customer]).setParameter("lastName", lastName).getResultList.toList
}
}
This is a quite standard DAO implementation but the real magic is in the implicit conversions of the java collections to scala collections. This can be achieved by adding “import scala.collection.JavaConversions._”. Now methods as toList are available on the collections. Keep in mind this is an example, doing “getAll” on a large dataset is not recommended.
Configuration
When using JPA you need a file called META-INF/persistence.xml. The one below is an example for JPA2.
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="JpaScala" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
</persistence-unit>
</persistence>
To wire all the code and libraries together I use the Spring Framework. The application-context below defines the following:
- Transaction manager
- JPA2 Entity manager
- Data source (Hypersonic memory database)
- Context scanner so it is able to find the spring annotated classes.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
">
<tx:annotation-driven transaction-manager="transactionManager"/>
<context:component-scan base-package="nl.paulhildebrand"/>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="org.hsqldb.jdbcDriver" p:url="jdbc:hsqldb:mem:JpaScala"
p:username="sa" p:password=""/>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="JpaScala"/>
<property name="persistenceProviderClass" value="org.hibernate.ejb.HibernatePersistence"/>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
</property>
<property name="dataSource" ref="dataSource"/>
<property name="jpaPropertyMap">
<map>
<entry key="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
<entry key="hibernate.connection.charSet" value="UTF-8"/>
<entry key="hibernate.hbm2ddl.auto" value="create"/>
<entry key="hibernate.show.sql" value="true"/>
</map>
</property>
</bean>
<bean id="entityManager"
class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
Try it out
The code below adds 5 customers to the database and shows them using various methods on the CustomerDao.
val ctx = new ClassPathXmlApplicationContext("application-context.xml")
val dao: CustomerDao = ctx.getBean(classOf[CustomerDao])
dao.save(new Customer("Paul", "Hildebrand"))
dao.save(new Customer("Floor", "Hildebrand"))
dao.save(new Customer("Storm", "Hildebrand"))
dao.save(new Customer("Jan", "Jansen"))
dao.save(new Customer("Peter", "Jansen"))
println(dao.getAll)
println(dao.getByLastName("Jansen"))
println(dao.getByLastName("Hildebrand"))
dao.find(3) match {
case Some(x) => println(x)
case None => println("No customer found with id 3")
}
Thoughts
With this example you should be able to write a simple JPA application using Scala. I have not yet tried to use things like case classes or many to one relations using Scala collections. You might also be able to improve the code using annotations in constructor arguments so that some “vars” can be replaced by “vals”.
For the dependency injection I used the Spring Framework because I use that a lot, but a framework like Guice works just as good.
This code might not work with Scala 2.7.x because of possible nested annotations.
Source code:
You can download the source code here.
For SBT users:
- unpack JpaScala.tar.gz
- start SBT in the root directory of JpaScala
- create new project
- do “update”
- do “run JpaScala”
If you have some improvements, please let me know. I am still quite new in the Scala world but I am learning fast.
feb 24th
This article is about how to create MBeans using annotations and spring. It assumes that you already have a MBean server available like the one in tomcat. Just follow the steps below.
First we want to create a Mbean, using the @Managed annotations you can convert any class you want into a MBean. The class MyMBean below is a very simple one which will only expose one method (i.e. getSomething). The @ManagedResource annotation will mark the class as a MBean. The @ManagedAttribute and @ManagedOperation annotations can be used to expose any attributes or methods. Also notice the @Component annotation, this annotation will make the MBean eligible for the spring context scanner.
package my.cool.app.mbean;
import org.springframework.jmx.export.annotation.ManagedOperation;
import org.springframework.jmx.export.annotation.ManagedResource;
import org.springframework.stereotype.Component;
@Component
@ManagedResource(objectName = "MyApp:name=MyMbean")
public class MyMBean {
@ManagedOperation(description = "Returns something.")
public String getSomething() {
return "Something";
}
}
Next, you will have to create a MBeanExporter in your spring application context. Normally just adding the <context:mbean-export/> element will do the trick but not in this case. You need a JmxAttributeSource which is capable of reading the @ManagedResouce annotations. The downside is that we have to make a more elaborate configuration which is not as beautiful as the short <context:mbean-export/> element.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!-- this bean must not be lazily initialized if the exporting is to happen -->
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter" lazy-init="false">
<property name="assembler" ref="assembler" />
<property name="namingStrategy" ref="namingStrategy" />
<property name="autodetect" value="true" />
</bean>
<bean id="jmxAttributeSource" class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource" />
<!-- will create management interface using annotation metadata -->
<bean id="assembler" class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
<property name="attributeSource" ref="jmxAttributeSource" />
</bean>
<!-- will pick up the ObjectName from the annotation -->
<bean id="namingStrategy" class="org.springframework.jmx.export.naming.MetadataNamingStrategy">
<property name="attributeSource" ref="jmxAttributeSource" />
</bean>
</beans>
But now spring still will not find any of your MBeans. Remember the @Component annotation (or @Named annotation if you are using jsr 330) at the class declaration of your MBean? Adding the component-scan element to your spring application context configuration will make sure all classes annotated with @Component, @Service or @Repository will be added to the spring context.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="my.cool.app.mbean" />
</beans>
That’s it. Good look with it.
dec 12th
This article is about installing scala 2.8.1 on ubuntu. Scala is also in the ubuntu repositories but then you get version 2.7.7. If you don’t mind using that version then skip the rest of the article and install using:
$ sudo apt-get install scala
It might be that you already have installed Scala on your ubuntu OS. You can remove it using the following command. (This step is not necessary).
$ sudo apt-get remove scala
Installing java development kit
In some cases Scala seems to have problems with openjdk-6 therefore we have to install the sun version of the JDK:
$ sudo apt-get install sun-java6-jdk
To make this the default java version do:
$ sudo update-java-alternatives -s java-6-sun
Make sure the right version is installed by:
$ java -version
Installing Scala
Download scala 2.8.1 from http://www.scala-lang.org/downloads and choose the unix version.
In this article Scala will be installed in /opt/scala/scala-2.8.1.final. But you can of-course choose to install it in another location. But make sure you change the paths shown here accordingly.
Open a terminal and go to the directory where you downloaded the file and do the following:
$ sudo mkdir -p /opt/scala $ sudo cp scala-2.8.1.final.tgz /opt/scala $ cd /opt/scala $ sudo tar -zxvf scala-2.8.1.final.tgz
Scala is now installed in /opt/scala/scala-2.8.1.final. We need to make to executables available on the path. Therefore we adjust the file ~/.bashrc in your home directory. Open the file with editor of choice and add at the end of the file:
export SCALA_HOME=/opt/scala/scala-2.8.1.final export PATH=$SCALA_HOME/bin:$PATH
Normally this would be the end of the installation, but I ran into some problems with the FSC (Fast Scala Compiler). If got the following exception while running scala HelloWorld.scala
Could not connect to compilation daemon.
Exception in thread "main" java.lang.Exception: fsc failure
at scala.tools.nsc.CompileSocket.fatal(CompileSocket.scala:50)
at scala.tools.nsc.CompileSocket.getPort(CompileSocket.scala:122)
at scala.tools.nsc.CompileSocket.getsock$1(CompileSocket.scala:152)
at scala.tools.nsc.CompileSocket.getOrCreateSocket(CompileSocket.scala:170)
at scala.tools.nsc.ScriptRunner$.compileWithDaemon(ScriptRunner.scala:145)
at scala.tools.nsc.ScriptRunner$.compile$1(ScriptRunner.scala:197)
at scala.tools.nsc.ScriptRunner$.withCompiledScript(ScriptRunner.scala:225)
at scala.tools.nsc.ScriptRunner$.runScript(ScriptRunner.scala:265)
at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:91)
at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
Normally if the FSC deamon is not started yet it should be started automatically but somehow this doesn’t work on my machine. Maybe it is to slow (Intel Atom A330) and gives a timeout before it is actually started? I can fix this by calling FSC manually first:
$ fsc Could not connect to compilation daemon. $ ps -ef | grep scala paulh 4234 1 30 15:24 pts/0 00:00:03 java -Xmx256M -Xms32M -cp /opt/scala/scala-2.8.1.final/lib/jline.jar:/opt/scala/scala-2.8.1.final/lib/scala-compiler.jar:/opt/scala/scala-2.8.1.final/lib/scala-dbc.jar:/opt/scala/scala-2.8.1.final/lib/scala-library.jar:/opt/scala/scala-2.8.1.final/lib/scala-swing.jar:/opt/scala/scala-2.8.1.final/lib/scalap.jar -Dscala.home=/opt/scala/scala-2.8.1.final -Denv.emacs= scala.tools.nsc.MainGenericRunner scala.tools.nsc.CompileServer
Although it says it could not connect to the compilation daemon, it was started anyway. Now all works like a charm.
I could add fsc to the ubuntu startup script but that isn’t a great solution to the problem, especially because Scala 2.7.7 which Ubuntu provides does not have this problem. If anyone has a better solution then please put it down this article.
Let’s hope that Ubuntu will upgrade scala in version 11.04.
dec 8th
As you can see there is not much here yet. I am still trying to figure out how this wordpress stuff works but I am making progress. In the future I hope to write down some of my experiences here.