NetBeans – Remote Java ARM debugging with GUI

There is a known issue related to NetBeans remote debugging a Java application with GUI enabled (Swing/JavaFX) running on embedded Linux (Raspberry Pi, BeagleBone Black etc.).

When one tries to run / debug an application with GUI components then java.awt.HeadlessException with “No X11 DISPLAY variable was set, but this program performed an operation which requires it” message is being thrown.

Long story short, the DISPLAY environment variable is empty and remotely run program does not know the display it is supposed to appear on – hence the error.

For my setup the problem was solved by small modification to ANT build XML script. I have found the “-copy-to-remote-platform” target, copied it to notepad++ and slightly modified it by adding highlighted lines.

Then I have pasted modified ANT target to build.xml file of my project to override the target (you can not just edit …-impl.xml file because your changes will be lost after each NetBeans restart or configuration changes).

Voila! Now I can run and debug my application remotely with GUI displayed on my BeagleBone Black 7” LCD display – pretty neat. One could modify my code to point a remote X server (like Xming) as a display.

<!-- Remote ARM linux deploy overwrite !-->
    <target name="-copy-to-remote-platform">
      <macrodef name="runwithpasswd" uri="http://www.netbeans.org/ns/j2se-project/remote-platform/1">
            <attribute name="additionaljvmargs" default=""/>
            <sequential>
                <sshexec host="${remote.platform.host}" port="${remote.platform.port}" username="${remote.platform.user}" password="${remote.platform.password}" trust="true" command="mkdir -p '${remote.dist.dir}'"/>
                <scp todir="${remote.platform.user}@${remote.platform.host}:${remote.dist.dir}" port="${remote.platform.port}" password="${remote.platform.password}" trust="true">
                    <fileset dir="${dist.dir}"/>
                </scp>
                <antcall target="profile-rp-calibrate-passwd"/>
                <sshexec host="${remote.platform.host}" port="${remote.platform.port}" username="${remote.platform.user}" password="${remote.platform.password}" trust="true" usepty="true"
                    command="export DISPLAY=:0; cd '${remote.project.dir}'; ${remote.platform.exec.prefix}'${remote.java.executable}' @{additionaljvmargs} -Dfile.encoding=${runtime.encoding} ${run.jvmargs} ${run.jvmargs.ide} -jar ${remote.dist.jar} ${application.args}"/>
            </sequential>
        </macrodef>
        <macrodef name="runwithkey" uri="http://www.netbeans.org/ns/j2se-project/remote-platform/1">
            <attribute name="additionaljvmargs" default=""/>
            <sequential>
                <fail unless="remote.platform.keyfile">Must set remote.platform.keyfile</fail>
                <sshexec host="${remote.platform.host}" port="${remote.platform.port}" username="${remote.platform.user}" keyfile="${remote.platform.keyfile}" passphrase="${remote.platform.passphrase}" trust="true" command="mkdir -p '${remote.dist.dir}'"/>
                <scp todir="${remote.platform.user}@${remote.platform.host}:${remote.dist.dir}" port="${remote.platform.port}" keyfile="${remote.platform.keyfile}" passphrase="${remote.platform.passphrase}" trust="true">
                    <fileset dir="${dist.dir}"/>
                </scp>
                <antcall target="profile-rp-calibrate-key"/>
                <sshexec host="${remote.platform.host}" port="${remote.platform.port}" username="${remote.platform.user}" keyfile="${remote.platform.keyfile}" passphrase="${remote.platform.passphrase}" trust="true" usepty="true"
                    command="export DISPLAY=:0; cd '${remote.project.dir}'; ${remote.platform.exec.prefix}'${remote.java.executable}' @{additionaljvmargs} -Dfile.encoding=${runtime.encoding} ${run.jvmargs} ${run.jvmargs.ide} -jar ${remote.dist.jar} ${application.args}"/>
            </sequential>
        </macrodef>
    </target>
Advertisements

Offline Pessimistic Lock in Entity Framework (or any other ORM)

I’ve always found surprising that so few projects were started with data access concurrency in mind. I’ve heard many discussions about new fancy frameworks and UI controls the teams were about to use but possibility of concurrent access to users’ data didn’t appear to be a concern in their minds.

Wen you think about it, it seems to be very logical. People have a natural tendency to avoid problems they haven’t encountered directly. There are so few people with attitude of challenging obstacles not laying directly on their path. And after all, most of the questions managers tend to ask are like “when will you finish this use case”, “how much will this cost”. Eventually, the more technical aware PMs ask for iPad or recent web browser support. I’ve never heard a manager asking for example “what will happen when user A edits invoice while user B is issuing a warehouse document ?” question.

The fact that software tools providers does not mention concurrency handling (but not only that) in context of using their tools doesn’t help at all. There are still so many people who acquire their knowledge mostly from Microsoft marketing hype and don’t ask themselves these kind of tough questions. It is also very significant that Microsoft’s flag ORM product – Entity Framework – implements out of the box only very limited optimistic concurrency mechanism which is not enough for most of the real world systems.

To shed some light on the concurrency issue I decided to show a real live example of Offline Pessimistic Lock pattern I’ve implemented in my recent project.

The Offline Pessimistic Lock is very useful pattern. It allows you to ensure that, for example, only one user is altering an object’s data. In my example it happens by creating a separate lock object on the whole document. This object contains information about the type of locked object (i.e. domain entity), it’s key and a user which holds this lock.

The LockManager class is responsible for acquiring, releasing and ensuring these locks. The lock objects are stored in WriteLocks table.

CREATE TABLE [dbo].[WriteLocks](
	[OBJECT_TYPE] [nvarchar](255) NOT NULL,
	[OBJECT_ID] [nvarchar](50) NOT NULL,
	[ACCOUNT_ID] [int] NOT NULL,
	[ACQ_TIMESTAMP] [datetime] NOT NULL,
 CONSTRAINT [PK_WriteLocks] PRIMARY KEY CLUSTERED 
(
	[OBJECT_TYPE] ASC,
	[OBJECT_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
namespace ATMS.Core.Concurrency
{
    public class LockManager
    {
        /// <summary>
        /// Utility method for showing information about existing lock on object
        /// </summary>
        public void ShowNotification(Control parent)
        {
            MessageBox.Show(Res.Lock_ObjectBeingLocked, string.Empty, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
        }

        /// <summary>
        /// Ensures that lock on the object already exists
        /// </summary>
        /// <typeparam name="TObj">Entity type</typeparam>
        /// <param name="id">Entity key</param>
        /// <returns>Returns true if lock acquired by current user exists; false otherwise</returns>
        public bool EnsureLock<TObj>(object id)
        {
            var user = UserInfo.Current;

            if (user == null)
                throw new InvalidOperationException("User not logged in - can not release write lock");

            var typeStr = typeof(TObj).FullName;
            var idStr = id.ToString();

            using (var ctx = CoreEntitiesBuilder.Build())
            {
                var exist = ctx.WriteLocks.FirstOrDefault(x => x.OBJECT_TYPE == typeStr && x.OBJECT_ID == idStr && x.ACCOUNT_ID == user.AccountId);
                return exist != null;
            }
        }

        /// <summary>
        /// Removes lock acquired on the object hence it is available for locking by other users
        /// </summary>
        /// <typeparam name="TObj">Entity type</typeparam>
        /// <param name="id">Entity key</param>
        /// <returns>Returns true if there was a lock to release; false otherwise</returns>
        public bool ReleaseLock<TObj>(object id)
        {
            var user = UserInfo.Current;

            if (user == null)
                throw new InvalidOperationException("User not logged in - can not release write lock");

            var typeStr = typeof(TObj).FullName;
            var idStr = id.ToString();

            using (var ctx = CoreEntitiesBuilder.Build())
            {
                var exist = ctx.WriteLocks.FirstOrDefault(x => x.OBJECT_TYPE == typeStr && x.OBJECT_ID == idStr);

                if (exist == null)
                    return true;

                if (exist != null && exist.ACCOUNT_ID == user.AccountId)
                {
                    ctx.WriteLocks.Remove(exist);
                    ctx.SaveChanges();
                    return true;
                }
                else
                    return false;
            }
        }

        /// <summary>
        /// Removes a batch of locks acquired on objects
        /// </summary>
        /// <typeparam name="TObj">Entity type</typeparam>
        /// <param name="ids">Entity keys</param>
        /// <returns>Returns true if all locks were successfully released; false otherwise</returns>
        public bool ReleaseLocks<TObj>(object[] ids)
        {
            var user = UserInfo.Current;

            if (user == null)
                throw new InvalidOperationException("User not logged in - can not release write lock");

            var typeStr = typeof(TObj).FullName;
            var idStr = ids.Select(x => x.ToString());

            using (var ctx = CoreEntitiesBuilder.Build())
            {
                var exist = ctx.WriteLocks.Where(x => x.OBJECT_TYPE == typeStr && idStr.Contains(x.OBJECT_ID)).ToArray();

                var canRemove = exist.Where(x => x.ACCOUNT_ID == user.AccountId).ToArray();
                var canNotRemove = exist.Where(x => x.ACCOUNT_ID != user.AccountId).ToArray();

                ctx.WriteLocks.RemoveRange(canRemove);
                ctx.SaveChanges();

                return !canNotRemove.Any();
            }
        }

        /// <summary>
        /// Acquire locks on list of objects
        /// </summary>
        /// <typeparam name="TObj">Entity type</typeparam>
        /// <param name="ids">Entity keys</param>
        /// <returns>Returns true when all locks where successfully acquired; false otherwise</returns>
        public bool AcquireLocks<TObj>(object[] ids)
        {
            var user = UserInfo.Current;

            if (user == null)
                throw new InvalidOperationException("User not logged in - can not acquire write lock");

            var typeStr = typeof(TObj).FullName;
            var idStr = ids.Select(x => x.ToString());
            var result = false;

            using (var ctx = CoreEntitiesBuilder.Build())
            {
                var existing = ctx.WriteLocks.Where(x => x.OBJECT_TYPE == typeStr && idStr.Contains(x.OBJECT_ID)).ToArray();

                if (!existing.Any() ||
                    existing.All(x => x.ACCOUNT_ID == user.AccountId))
                {
                    foreach (var ex in existing)
                        ex.ACQ_TIMESTAMP = DateTime.Now;

                    var notExisting = idStr
                        .Where(x => !existing.Any(e => e.OBJECT_ID == x))
                        .Select(x => new WriteLocks()
                        {
                            ACCOUNT_ID = user.AccountId,
                            ACQ_TIMESTAMP = DateTime.Now,
                            OBJECT_ID = x,
                            OBJECT_TYPE = typeStr
                        });

                    try
                    {
                        ctx.WriteLocks.AddRange(notExisting);
                        ctx.SaveChanges();

                        result = true;
                    }
                    catch (SqlException)
                    {
                        result = false;
                    }
                }
                else
                    result = false;
            }

            return result;
        }

        /// <summary>
        /// Acquire lock on a single object
        /// </summary>
        /// <typeparam name="TObj">Entity type</typeparam>
        /// <param name="id">Entity key</param>
        /// <returns>Returns true when lock was acquired successfully; false otherwise</returns>
        public bool AcquireLock<TObj>(object id)
        {
            var user = UserInfo.Current;

            if (user == null)
                throw new InvalidOperationException("User not logged in - can not acquire write lock");

            var typeStr = typeof(TObj).FullName;
            var idStr = id.ToString();
            var result = false;

            using (var ctx = CoreEntitiesBuilder.Build())
            {
                var exist = ctx.WriteLocks.FirstOrDefault(x => x.OBJECT_TYPE == typeStr && x.OBJECT_ID == idStr);

                if (exist != null && exist.ACCOUNT_ID == user.AccountId)
                {
                    exist.ACQ_TIMESTAMP = DateTime.Now;
                    ctx.SaveChanges();

                    result = true;
                }
                else if (exist != null && exist.ACCOUNT_ID != user.AccountId)
                {
                    result = false;
                }
                else
                {
                    try
                    {
                        ctx.WriteLocks.Add(new WriteLocks()
                        {
                            ACCOUNT_ID = user.AccountId,
                            ACQ_TIMESTAMP = DateTime.Now,
                            OBJECT_ID = idStr,
                            OBJECT_TYPE = typeStr
                        });
                        ctx.SaveChanges();

                        result = true;
                    }
                    catch (SqlException)
                    {
                        result = false;
                    }
                }
            }

            return result;
        }
    }
}

Here are some examples of LockManager class usage:

private void btnSave_Click(object sender, EventArgs e)
{
	this.WithDbErrorHandling(
		() =>
		{
			if (!_lockMan.EnsureLock<rcr_CVDocument>(_currentDocument.ID))
			{
				_lockMan.ShowNotification(this);
				
				// ... 
			}
			else
				SaveDocumentData(_currentDocument.ID);
			
			// .... update UI controls etc.
		}
}

private void btnDelete_Click(object sender, EventArgs e)
{
	if (!_lockMan.AcquireLock<rcr_CVDocument>(_currentDocument.ID))
	{
		_lockMan.ShowNotification(this);
		return;
	}

	try
	{
		_currentDocument.TO_DELETE = true; //real delete handled by backend worker
		_entities.SaveChanges();
	}
	finally
	{
		_lockMan.ReleaseLock<rcr_CVDocument>(_currentDocument.ID);
	}
}

For further reading I suggest:

Cheap web-cam monitoring in the Cloud with raspberry pi, ASP.NET MVC and Marionette.js

I’ve recently seen a few articles about video streaming with raspberry pi using node.js streaming server and ffmpeg utility. It’s funny how easily you can create your own live video streaming with opensource tools and cheap mini-computer. But there are some problems with this approach. The highest resolution I was able to capture, encode and live stream was 160×120. It is too low to recognize people or plate numbers seen on the picture. There are also some network issues that make things harder like maximum throughput, security and it requires you to have public IP.

All this issues made me wander if wouldn’t be better to capture fewer frames (1 per second or even per few seconds) but with higher quality – maybe event in HD which is not a problem for today’s webcams. If you have a bunch of time-stamped HD images you will be able to identify people or event read a plate numbers of passing cars etc. To overcome network issues I’ve decided to give OpenStack Object Storage (hosted by oktawave) a try.

First thing I had to do was to plug a webcam to my raspberry pi board and get it connected to my access-point.

WP_20150822_005

Then I had to upload two utilities from linux repositories. The first one was fswebcam used for capturing webcam image and the other one was imagemagick used for comparing pictures in order to avoid uploading duplicated images (when nothing happens in front of the camera there is no need to use cloud storage you for which you pay).

Then I have written a simple python script (available at my github) which generally does the following:

  1. authenticate against open-stack object storage,
  2. create directory for new snapshot (/camera-name/year/month/day/hour/),
  3. take a snapshot and compare it with previous one,
  4. upload picture to storage if it is different enough from the previous one,
  5. go to step 2.

The result of running this script on my raspberry was visible on my administration panel provided by Oktawave.

list

Using administration was not the most convenient way to browse my captured photos so I decided to use ASP.NET MVC 5, bootstrap and Marionette.js to create a simple browser of my data. The whole solution is also available on my github.

The app is very straightforward and it looks as in the picture below.

capture

The whole project is available on github. This is just a PoC but it’s amazing how easily you can create something fun and useful with these days’ toys.

SoftProTech on AirFair 2015 Exposition

During the AirFair 2015 Expisition (an international event for military and aviation business) together with our business partner  – Military Aviation Works Facility – and TELDAT (award winning Polish defense market company) we have exhibited our company solutions – an Augmented Reality presentation of Military Aviation Works drone and a flight simulator designed for its pilots training.

Here are a few photos:

1 2 3 4

SoftReality – promo clip

A promo clip of our recent product – SoftReality. It allows us to create astonishing, Virtual Reality presentations for our customers.

There are no English subtitles yet.

A talk about implementing modular architecture in web UI

During 11th edition of Bydgoszcz Web Development Meetup (in Bydgoszcz, Poland) I’ve given a talk about suggested approach for implementing modular architecture in web applications.

My talk covered some best practices, design patterns and JavaScript Object Oriented Code.

Here is the video (in Polish – no subtitles yet):

And a presentation in PDF:

http://www.softprotech.pl/wp-content/uploads/2015/03/Modu%C5%82owe-systemy.pdf

New opensource project

I’ve recently created an util class that might be helpful while working with communication data protocols: https://github.com/mkarczewski/BinaryMask.