Aug 142015
 

Wow, 8 whole years have passed since Lora left us. I feel old.

Looking forward is my thing, looking back - I've always had a difficulty doing it. It makes me reminisce but in a melancholic way. I have very large white spots in regards to my past. I guess my brains likes forgetting.

The weird part is that two very close friends have birthdays today. Mixed feelings.

Checking the old pictures makes me smile - there isn't a single boring picture with Lora. Rest in peace.

A bunch of pics I gathered: http://picasaweb.google.com/mihail.stoynov/InMemoriamLorkis
More pics from friends: http://picasaweb.google.com/renkata/ByPUWK

My personal Lora song: Eva Cassidy - Autumn Leaves

Aug 122015
 

So this weekend the Bulgarian Java User Group (jug.bg) organized a hackaton to try to create a JBoss Forge plugin to create Spring Boot applications.

JBoss Forge is a tool to ease development. Main traits are it can create JPA entities, It can create an example REST interface to those entities, a web interface to those entities and it integrates with Eclipse and IntelliJ IDEA:

Screen Shot 2015-08-12 at 11.51.02

Cmd+Option+4 in IDEA on OSX, Ctrl+4 in Eclipse on Windows

The code is here. Here are a couple of pictures from the event:

IMG_5514 IMG_5515IMG_5513

 

Jul 312015
 

My WordPress installation's CPU started gradually spiking. Using P3, I found out that a stat plugin was abusing my installation

Before deinstallation:

Screen Shot 2015-07-31 at 14.24.22

Plugin CPU hog.

After removing pixelstats:

Screen Shot 2015-07-31 at 14.28.29

After removing the cpu hog

I saved almost a second on initial load. How have I lived like this for so long?

 

Jul 292015
 

The last day of jCrete was with two hacking sessions - one on optimizing a NES emulator (if I got it correctly) and one on building a Lego and writing some software on LeJOS and EV3 controller (ARM processor inside).

This is what we did (@claudiotagliola did more than I have):

lego IMG_5263 IMG_5266

We used LeJOS, with LeJOS plugin for eclipse, initial code we got from Steven's presentation on the subject,  but we decided not to build the thing shown on the presentation.

We built a pretty bulky two-motor lego using snow-chains. We installed a server app that listened on a port and we sent it commands using a awt/swing app.

Videos:

Here's the code:

The app installed on the device:

package jcrete.hacking;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

import lejos.hardware.Button;
import lejos.hardware.Key;
import lejos.hardware.KeyListener;
import lejos.hardware.motor.EV3LargeRegulatedMotor;
import lejos.hardware.port.MotorPort;
import lejos.utility.Delay;

/**
 * This was written on jCrete 2015 on a LeJOS session by Steven Chin.
 * 
 * We were given the task to build a lego and do something cool with it.
 * We built a pretty large tank and remote-controlled it via wi-fi with
 * simple socket commands.
 * 
 * For more info, go to http://mihail.stoynov.com/?p=2909
 * 
 * This is a mock server for testing if you don't have a lego at hand.
 * 
 * @author Nayden Gochev, jug.bg
 * @author Mihail Stoynov, jug.bg
 *
 */
public class E3vRemoteControlCarApp {

	static boolean isRunning = true;

	public static void main(String[] args) throws IOException {

		try (
				final EV3LargeRegulatedMotor leftMottor = new EV3LargeRegulatedMotor(MotorPort.B);
				final EV3LargeRegulatedMotor rightMottor = new EV3LargeRegulatedMotor(MotorPort.C);
				ServerSocket serv = new ServerSocket(19231);
				) {

			Socket socket = serv.accept();
			BufferedReader reader = new BufferedReader(new InputStreamReader(
					socket.getInputStream()));

			// if we use the buttons on the device directly
			Button.UP.addKeyListener(new KeyListener() {

				@Override
				public void keyReleased(Key k) {
					leftMottor.stop(true);
					rightMottor.stop(true);
				}

				@Override
				public void keyPressed(Key k) {
					leftMottor.setSpeed(1500);
					leftMottor.setAcceleration(150);
					leftMottor.forward();
					rightMottor.setSpeed(1500);
					rightMottor.setAcceleration(150);
					rightMottor.forward();

				}
			});

			Button.DOWN.addKeyListener(new KeyListener() {

				@Override
				public void keyReleased(Key k) {
					leftMottor.stop(true);
					rightMottor.stop(true);
				}

				@Override
				public void keyPressed(Key k) {
					leftMottor.setSpeed(1500);
					leftMottor.setAcceleration(150);
					leftMottor.backward();
					rightMottor.setSpeed(1500);
					rightMottor.setAcceleration(150);
					rightMottor.backward();

				}
			});

			Button.RIGHT.addKeyListener(new KeyListener() {

				@Override
				public void keyReleased(Key k) {
					rightMottor.stop(true);
					leftMottor.stop(true);
				}

				@Override
				public void keyPressed(Key k) {
					rightMottor.setSpeed(1500);
					rightMottor.setAcceleration(150);
					rightMottor.forward();
					leftMottor.setSpeed(1500);
					leftMottor.setAcceleration(150);
					leftMottor.backward();
				}
			});

			Button.LEFT.addKeyListener(new KeyListener() {

				@Override
				public void keyReleased(Key k) {
					rightMottor.stop(true);
					leftMottor.stop(true);
				}

				@Override
				public void keyPressed(Key k) {
					rightMottor.setSpeed(1500);
					rightMottor.setAcceleration(150);
					rightMottor.backward();
					leftMottor.setSpeed(1500);
					leftMottor.setAcceleration(150);
					leftMottor.forward();
				}
			});

			Button.ESCAPE.addKeyListener(new KeyListener() {

				@Override
				public void keyReleased(Key k) {
				}

				@Override
				public void keyPressed(Key k) {
					E3vRemoteControlCarApp.isRunning = false;
				}
			});


			// we copied it from somewhere, not necessary
			Delay.msDelay(3000);


			// the listener with the while readline
			String line;
			while ((line = reader.readLine()) != "STOP" && isRunning) {
				System.out.println("RECIEVED " + line);
				switch (line) {
				case "UP-PRESS":
					leftMottor.setSpeed(1500);
					// leftMottor.setAcceleration(150);
					leftMottor.forward();
					rightMottor.setSpeed(1500);
					// rightMottor.setAcceleration(150);
					rightMottor.forward();
					break;
				case "UP-RELEASE":
					leftMottor.stop(true);
					rightMottor.stop(true);
					break;
				case "DOWN-PRESS":
					leftMottor.setSpeed(1500);
					// leftMottor.setAcceleration(150);
					leftMottor.backward();
					rightMottor.setSpeed(1500);
					// rightMottor.setAcceleration(150);
					rightMottor.backward();
					break;
				case "DOWN-RELEASE":
					leftMottor.stop(true);
					rightMottor.stop(true);
					break;
				case "LEFT-PRESS":
					rightMottor.setSpeed(1500);
					// rightMottor.setAcceleration(150);
					rightMottor.backward();
					leftMottor.setSpeed(1500);
					// leftMottor.setAcceleration(150);
					leftMottor.forward();
					break;
				case "LEFT-RELEASE":
					rightMottor.stop(true);
					leftMottor.stop(true);
					break;
				case "RIGHT-PRESS":
					rightMottor.setSpeed(1500);
					// rightMottor.setAcceleration(150);
					rightMottor.forward();
					leftMottor.setSpeed(1500);
					// leftMottor.setAcceleration(150);
					leftMottor.backward();
					break;
				case "RIGHT-RELEASE":
					rightMottor.stop(true);
					leftMottor.stop(true);
					break;
				case "STOP":
					E3vRemoteControlCarApp.isRunning = false;
					break;
				}
			}
		}
	}
}

 

The controller:

import java.awt.BorderLayout;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
 
import javax.swing.JButton;
import javax.swing.JFrame;
 
/**
/**
 * This was written on jCrete 2015 on a LeJOS session by Steven Chin.
 * 
 * We were given the task to build a lego and do something cool with it.
 * We built a pretty large tank and remote-controlled it via wi-fi with
 * simple socket commands.
 * 
 * For more info, go to http://mihail.stoynov.com/?p=2909
 * 
 * This is a mock server for testing if you don't have a lego at hand.
 * 
 * @author Nayden Gochev, jug.bg
 * @author Mihail Stoynov, jug.bg
 *
 */
public class Remote extends JFrame {
 
	private static final long serialVersionUID = -8402983606638099877L;
 
	private final JButton left;
	private final JButton right;
	private final JButton up;
	private final JButton down;
	private final JButton stop;
 
	private BufferedWriter pw;
 
	public static void main(String[] args) {
		Remote remote = new Remote();
		remote.setSize(500, 500);
		remote.setVisible(true);
	}
 
	public Remote() {
		try {
			Socket socket = new Socket("192.168.0.107", 19231);
//			Socket socket = new Socket("127.0.0.1", 19231);//for mocking
			pw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
 
		setLayout(new BorderLayout());
 
 
 
		left = new JButton("LEFT");
		this.getContentPane().add(left, BorderLayout.WEST);
		left.addMouseListener(new MouseAdapter() {
 
			@Override
			public void mouseReleased(MouseEvent e) {
				leftRelease();
//				System.out.println("LEFT-RELEASE\n");pw.flush();
			}
 
 
			@Override
			public void mousePressed(MouseEvent e) {
				leftPress();
//				System.out.println("LEFT-PRESS\n");pw.flush();
			}
 
 
		});
		right = new JButton("RIGHT");
		this.getContentPane().add(right, BorderLayout.EAST);
		right.addMouseListener(new MouseAdapter() {
 
			@Override
			public void mouseReleased(MouseEvent e) {
				rightRelease();
//				System.out.println("RIGHT-RELEASE\n");pw.flush();
			}
 
 
 
			@Override
			public void mousePressed(MouseEvent e) {
				rightPress();
//				System.out.println("RIGHT-PRESS\n");pw.flush();
			}
 
 
		});
		up = new JButton("UP");
		this.getContentPane().add(up, BorderLayout.NORTH);
		up.addMouseListener(new MouseAdapter() {
 
			@Override
			public void mouseReleased(MouseEvent e) {
				upRelease();
//				System.out.println("UP-RELEASE\n");pw.flush();
			}
 
 
 
			@Override
			public void mousePressed(MouseEvent e) {
				upPress();
//				System.out.println("UP-PRESS\n");pw.flush();
			}
 
 
		});
		down = new JButton("DOWN");
		this.getContentPane().add(down, BorderLayout.SOUTH);
		down.addMouseListener(new MouseAdapter() {
 
			@Override
			public void mouseReleased(MouseEvent e) {
				downRelease();
//				System.out.println("DOWN-RELEASE\n");
			}
 
 
 
			@Override
			public void mousePressed(MouseEvent e) {
				downPress();
//				System.out.println("DOWN-PRESS\n");
			}
 
 
		});
		stop = new JButton("STOP\n");
		this.getContentPane().add(stop, BorderLayout.CENTER);
		stop.addMouseListener(new MouseAdapter() {
 
			@Override
			public void mousePressed(MouseEvent e) {
				sendCommand("STOP");
			}
		});
 
		//keypad arrows work only if the focus is on the stop button
		//lame but that's life
		stop.addKeyListener(new KeyListener() {
			@Override
			public void keyTyped(KeyEvent event) {
				// TODO Auto-generated method stub
 
			}
 
			@Override
			public void keyReleased(KeyEvent event) {
				if(KeyEvent.VK_UP == event.getKeyCode()){
					upRelease();
				} else if(KeyEvent.VK_DOWN == event.getKeyCode()){
					downRelease();
				} else if(KeyEvent.VK_LEFT == event.getKeyCode()){
					leftRelease();
				} else if(KeyEvent.VK_RIGHT == event.getKeyCode()){
					rightRelease();
				}
			}
 
			@Override
			public void keyPressed(KeyEvent event) {
				if(KeyEvent.VK_UP == event.getKeyCode()){
					upPress();
				} else if(KeyEvent.VK_DOWN == event.getKeyCode()){
					downPress();
				} else if(KeyEvent.VK_LEFT == event.getKeyCode()){
					leftPress();
				} else if(KeyEvent.VK_RIGHT == event.getKeyCode()){
					rightPress();
				}
			}
		});
 
 
		pack();
	}
 
	private void downPress() {
		sendCommand("DOWN-PRESS");
	}
 
	private void sendCommand(String command) {
		try {
			pw.write(command+"\n");pw.flush();
		} catch (IOException e1) {
			e1.printStackTrace();
		}
	}
 
	private void downRelease() {
		sendCommand("DOWN-RELEASE");
	}
 
	private void leftPress() {
		sendCommand("LEFT-PRESS");
	}
 
	private void upRelease() {
		sendCommand("UP-RELEASE");
	}
 
	private void leftRelease() {
		sendCommand("LEFT-RELEASE");
	}
	private void rightRelease() {
		sendCommand("RIGHT-RELEASE");
	}
 
	private void upPress() {
		sendCommand("UP-PRESS");
	}
 
	private void rightPress() {
		sendCommand("RIGHT-PRESS");
	}
}

 

Mock app to test the remote:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * This was written on jCrete 2015 on a LeJOS session by Steven Chin.
 * 
 * We were given the task to build a lego and do something cool with it.
 * We built a pretty large tank and remote-controlled it via wi-fi with
 * simple socket commands.
 * 
 * For more info, go to http://mihail.stoynov.com/?p=2909
 * 
 * This is a mock server for testing if you don't have a lego at hand.
 * 
 * @author Nayden Gochev, jug.bg
 * @author Mihail Stoynov, jug.bg
 *
 */
public class ServerMock {
	public static void main(String[] args) throws IOException {
		try (ServerSocket server = new ServerSocket(19231);) {
			Socket socket = server.accept();
			System.out.println("ACCEPTING");
			BufferedReader reader = new BufferedReader(
					new InputStreamReader(
							socket.getInputStream()));
	
			System.out.println(reader.readLine());
			String line;
			while ((line = reader.readLine()) != null) {
				System.out.println("RECIEVED " + line);
			}
		}
	}
}
Jul 292015
 

IMG_5449

I've had issues powering an external hdd on a raspberry pi or odroid. I had to buy Y-cable (Y-cable = branched USB cord for dual power).

I found out, that powering the raspberry pi or odroid on the normal USB supplies more power than on the mini/micro-USB they use. The micro/mini USB used for power has a fuse that cannot supply more than 1A, but powering via one of the USB typeA works fine. Of course you would need a Y-cable, because even the most powerful USB chargers cannot produce enough power on one port.

That's another point - most USB chargers say they produce 2A or 2.1A and the crappy ones produce .3A, the good ones go up to .9A. So everybody lies. But .9A is good enough with a Y-cable.

The PI/Odroid use like .5A, the drive uses .3A, but they spike to more than 1Amp.

Jul 232015
 

jCrete is an unconference organized by Heinz Kabutz (author of the Java Specialist newsletter).

*unconference - top people, informal talks, discussions instead of sessions (most in a restaurant or at the beach).

What I learned:

Unsafe is going to be available in jdk9 with a jre switch on startup. Oracle is working on isolating (boundary checks) the unmanaged heap so that

  • mistakes will not mess up the managed heap
  • mistakes will not cause a segmentation fault (crash the whole jvm, because someone is trying to read memory from another process)

Oracle might introduce a commercial GC with deterministic stop-the-world pauses.

G1 will become the default GC in jdk9.

I will update this accordingly with more info.

Jul 142015
 

If I want to use the latest JDK9 build in IntelliJ, I get:

Screen Shot 2015-07-14 at 11.48.37

To fix it, I have to fix /Applications/IntelliJ IDEA 14.app/Contents/Info.plist

Screen Shot 2015-07-14 at 13.36.55

Restart. Should work.

So far no issues with IDEA, but I expect to see some.

Jul 142015
 

Screen Shot 2015-07-14 at 11.35.31

A bug report here: https://bugs.openjdk.java.net/browse/JDK-8065424

Information:Using javac 1.8.0_25 to compile java sources
Information:java: An exception has occurred in the compiler (1.8.0_25). Please file a bug at the Java Developer Connection (http://java.sun.com/webapps/bugreport) after checking the Bug Parade for duplicates. Include your program and the following diagnostic in your report. Thank you.
Information:java: java.lang.NullPointerException
Information:java: at com.sun.tools.javac.code.Types.isConvertible(Types.java:290)
Information:java: at com.sun.tools.javac.comp.Check.assertConvertible(Check.java:922)
Information:java: at com.sun.tools.javac.comp.Check.checkMethod(Check.java:876)
Information:java: at com.sun.tools.javac.comp.Attr.checkMethod(Attr.java:3838)
Information:java: at com.sun.tools.javac.comp.Attr.checkIdInternal(Attr.java:3615)
Information:java: at com.sun.tools.javac.comp.Attr.checkMethodIdInternal(Attr.java:3522)
Information:java: at com.sun.tools.javac.comp.Attr.checkMethodId(Attr.java:3501)
Information:java: at com.sun.tools.javac.comp.Attr.checkId(Attr.java:3488)
Information:java: at com.sun.tools.javac.comp.Attr.visitIdent(Attr.java:3237)
Information:java: at com.sun.tools.javac.tree.JCTree$JCIdent.accept(JCTree.java:2011)
Information:java: at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:607)
Information:java: at com.sun.tools.javac.comp.Attr.visitApply(Attr.java:1843)
Information:java: at com.sun.tools.javac.tree.JCTree$JCMethodInvocation.accept(JCTree.java:1465)
Information:java: at com.sun.tools.javac.comp.Attr.visitReturn(Attr.java:1704)
Information:java: at com.sun.tools.javac.tree.JCTree$JCReturn.accept(JCTree.java:1384)
Information:java: at com.sun.tools.javac.comp.Attr.attribStat(Attr.java:676)
Information:java: at com.sun.tools.javac.comp.Attr.attribStats(Attr.java:692)
Information:java: at com.sun.tools.javac.comp.Attr.visitBlock(Attr.java:1142)
Information:java: at com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:909)
Information:java: at com.sun.tools.javac.comp.Attr.visitMethodDef(Attr.java:1035)
Information:java: at com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:778)
Information:java: at com.sun.tools.javac.comp.Attr.attribClassBody(Attr.java:4342)
Information:java: at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:4252)
Information:java: at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:4181)
Information:java: at com.sun.tools.javac.comp.Attr.visitClassDef(Attr.java:892)
Information:java: at com.sun.tools.javac.tree.JCTree$JCClassDecl.accept(JCTree.java:693)
Information:java: at com.sun.tools.javac.comp.Attr.attrib(Attr.java:4156)
Information:java: at com.sun.tools.javac.main.JavaCompiler.attribute(JavaCompiler.java:1248)
Information:java: at com.sun.tools.javac.main.JavaCompiler.compile2(JavaCompiler.java:901)
Information:java: at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:860)
Information:java: at com.sun.tools.javac.main.Main.compile(Main.java:523)
Information:java: at com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:129)
Information:java: at com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:138)
Information:java: at org.jetbrains.jps.javac.JavacMain.compile(JavacMain.java:168)
Information:java: at org.jetbrains.jps.incremental.java.JavaBuilder.compileJava(JavaBuilder.java:382)
Information:java: at org.jetbrains.jps.incremental.java.JavaBuilder.compile(JavaBuilder.java:296)
Information:java: at org.jetbrains.jps.incremental.java.JavaBuilder.doBuild(JavaBuilder.java:204)
Information:java: at org.jetbrains.jps.incremental.java.JavaBuilder.build(JavaBuilder.java:176)
Information:java: at org.jetbrains.jps.incremental.IncProjectBuilder.runModuleLevelBuilders(IncProjectBuilder.java:1196)
Information:java: at org.jetbrains.jps.incremental.IncProjectBuilder.runBuildersForChunk(IncProjectBuilder.java:877)
Information:java: at org.jetbrains.jps.incremental.IncProjectBuilder.buildTargetsChunk(IncProjectBuilder.java:945)
Information:java: at org.jetbrains.jps.incremental.IncProjectBuilder.buildChunkIfAffected(IncProjectBuilder.java:840)
Information:java: at org.jetbrains.jps.incremental.IncProjectBuilder.buildChunks(IncProjectBuilder.java:663)
Information:java: at org.jetbrains.jps.incremental.IncProjectBuilder.runBuild(IncProjectBuilder.java:370)
Information:java: at org.jetbrains.jps.incremental.IncProjectBuilder.build(IncProjectBuilder.java:191)
Information:java: at org.jetbrains.jps.cmdline.BuildRunner.runBuild(BuildRunner.java:137)
Information:java: at org.jetbrains.jps.cmdline.BuildSession.runBuild(BuildSession.java:293)
Information:java: at org.jetbrains.jps.cmdline.BuildSession.run(BuildSession.java:124)
Information:java: at org.jetbrains.jps.cmdline.BuildMain$MyMessageHandler$1.run(BuildMain.java:242)
Information:java: at org.jetbrains.jps.service.impl.SharedThreadPoolImpl$1.run(SharedThreadPoolImpl.java:41)
Information:java: at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
Information:java: at java.util.concurrent.FutureTask.run(FutureTask.java:266)
Information:java: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
Information:java: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
Information:java: at java.lang.Thread.run(Thread.java:745)
Information:java: Errors occurred while compiling module 'xj-conc-j8'
Information:7/14/15, 11:22 - Compilation completed with 1 error and 0 warnings in 2s 319ms
Error:java: Compilation failed: internal java compiler error
Jun 292015
 

Today we had a BGJUG event.

Martin presented RabbitMQ - Spring Framework's default message broker.
IMG_4964 IMG_4966

 

I followed the presentation and using Docker's GUI for OSX called Kitematic, easily created a rabbitmq server and a client in a maven project:

Screen Shot 2015-06-29 at 20.51.51Screen Shot 2015-06-29 at 21.07.04

Again there was a lot of beer, but since we have been accused of advertising beer brands, there will be no pics.