The perception of power (of 9 volts)

When travelling I want to arrive at my destination ontime and unhurt.  I do appreciate that the world’s governments are just as interested and do take steps to ensure that dangerous people don’t hijack the plane or even worse.

Unfortunately sometimes I think that these agencies designed to protect us sometimes feel that they must constantly change something in order to show that they are still keeping us safe – even if the change doesn’t really help.  They think, as do I, that perception matters and if everyone sees them trying really hard then they will think they are being very successful.

That isn’t really the case.  I realize that bringing box cutters on the plane is a bad idea but it is fairly obvious to most rational people that bringing on fingernail clippers is fine.  It is being kind to call some of these “safety” choices as a bit overzealous.

That last sentence was echoing in my head when I read a quote from a TSA official Camille Morris about batteries.  She seems to suggest that a single AA battery is fine as is a single AAA battery, but a common 9 volt battery a big problem.

Actually 9 volt batteries may be a big problem. I cannot say which is the most beloved battery in home made explosives but unfortunately for Miss Morris batteries with smaller voltages can be combined in series to create a battery with a higher voltage.

If a 9volt battery is serious, then, I am rather curious what the TSA thinks about laptops and other larger devices that contain even more powerful batteries.  Let us hope not. What are people supposed to do with their devices.  Laptops filled with lithium batteries.  These are coincidentally the same batteries that the airplane companies work so hard at to ensure they are safely incorporated into and transported using planes.

The FAA Is Freaked Out About Lithium-Ion Batteries on Planes

Crash: UPS B744 at Dubai on Sep 3rd 2010, cargo fire

I might be even more worried about a plane with a belly full of laptops and other assorted battery carrying devices than seeing a tablet in the hand of the guy sitting next to me.

Christmas will be here soon, hopefully there will not be a new batch of “keep us safe” suggestions from the TSA.  We will see if I am still able to board with with a tablet or if that device goes into the naughty stack.

Posted in Soapbox | Tagged | Leave a comment

coding like it is 1996

It is a sad fact but I don’t always get to pick the tools I use at work.  Just today I felt like my colleague and I woke up in 1996 – back when java 1.6 was released.

The client wanted to keep track of all record changes in one of the fields – the history field.  I am not sure how the other consultancy firm convinced them to do that instead of having either a log file or putting the logging information into a separate table.

The plan was to store all the record changes in the history field in JSON format.  The JSON format is actually great for holding the information in an easy to use format but that is true only with a good parsing class.

That is where our problems began.  We were given the task of dealing with JSON data but the boss said we couldn’t use anything that didn’t come standard with Java 1.6.  This meant that we couldn’t use google’s solution GSON or any other external libraries.

We kicked  a few ideas around before we decided we could use the StringTokenizer class to split up the JSON strings.  Our solution works but only because there is only a single array of records.

We did some rudimentary parsing of the data, but it still felt like going back to pre-internet where you had to write every function yourself for formatting every little thing.

package my.json;
 
import java.util.StringTokenizer;
 
public class TestJson {
 
       public String mydata = "[{\"Date\":\"2017-10-20 16:55\",\"User\":\"Interface\",\"Action\":\"Create\",\"Type\":\"INTERFACE\",\"UserComment\":\"Item created\",\"Level\":\"info\",\"Details\":\"Item created\",\"NotificationStatus\":\"\",\"NotificationReason\":\"\",\"NotificationMessage\":\"\"},{\"Date\":\"2017-10-20 17:35\",\"User\":\"Interface\",\"Action\":\"email\",\"Type\":\"INTERFACE\",\"UserComment\":\"Sending\",\"Level\":\"error\",\"Details\":\"Item created\",\"NotificationStatus\":\"Notification Overdue\",\"NotificationReason\":\"Overdue\",\"NotificationMessage\":\"\"},{\"Date\":\"2017-10-20 17:41\",\"User\":\"Interface\",\"Action\":\"email\",\"Type\":\"INTERFACE\",\"UserComment\":\"Sending\",\"Level\":\"error\",\"Details\":\"Item created\",\"NotificationStatus\":\"Notification Overdue\",\"NotificationReason\":\"Overdue\",\"NotificationMessage\":\"\"}]";
       public String newrec = "{\"Date\":\"2017-10-20 17:41\",\"User\":\"Interface\",\"Action\":\"email\",\"Type\":\"INTERFACE\",\"UserComment\":\"Sending\",\"Level\":\"error\",\"Details\":\"Item created\",\"NotificationStatus\":\"Notification Overdue\",\"NotificationReason\":\"Overdue\",\"NotificationMessage\":\"\"}";
   
       public void printValue(int idx, String datapair)
       {
             StringTokenizer tok = new StringTokenizer(datapair, "\":");
             String key = tok.nextToken();
             String value = "";
             if (tok.hasMoreTokens())
                    value = tok.nextToken();
 
             key = (key + "                   ").substring(0,22);
             System.out.println(idx++ + " " + key + "  " + value);;
       }
 
       public void printfields(String data)
       {
             System.out.println(data);
             StringTokenizer tok = new StringTokenizer(data, "[]{},");
             if (tok.hasMoreElements() == false)
                    return;
             int idx = 0;
             do
             {
                    String str = tok.nextToken();
                    printValue(idx,str);
                    idx++;
             }
             while (tok.hasMoreElements() == true);
       }
       public void process (String args[])
       {
             StringTokenizer tok = new StringTokenizer(mydata, "}");
             do
             {
                    String str = tok.nextToken();
                    printfields(str);
                    System.out.println("\n");
             }
             while (tok.hasMoreElements() == true);
       }
 
       public int ItemCount(String data)
       {
             int retval = 0;
 
             if (data.length() == 0)
                    return 0;
             data = data.replace("[", "").replace("]", "");
             String parts[] = data.split("}");
             retval = parts.length;
             return retval;
       }
       public String getItem(int item, String data)
       {
             String retval = "";
 
             try {
                    data = data.replace("[", "").replace("]", "");
                    if (data.subSequence(0, 1).equals(","))
                          data = data.substring(1);
                    String parts[] = data.split("}");
 
                    if (parts[item].substring(0,1).equals(","))
                          retval = parts[item].substring(1) + "}";
                    else
                          retval = parts[item] + "}";
             }
             catch (ArrayIndexOutOfBoundsException ex)
             {
                    retval = null;
             }
             return  retval;
       }
       public String getItem(int item)
       {
             return getItem(item,mydata);
       }
       public int ItemCount()
       {
             return ItemCount(mydata);
       }
 
       public TestJson()
       {
 
       }
       public TestJson(String record)
       {
             mydata = record;
       }
       static public void main (String args[])
       {
             TestJson x = new TestJson();
             System.out.println(x.ItemCount());
             System.out.println(x.ItemCount(x.newrec));
             System.out.println(x.ItemCount(""));
 
             System.out.println(x.getItem(0));
             System.out.println(x.getItem(1));
             System.out.println(x.getItem(2));
             System.out.println(x.getItem(3));
       }
}
Posted in programming | Tagged , | Leave a comment

windows batch processing

I really didn’t want to fool around with that little windows task that has been laying on my boss’s desk. It was planned that Robert would do it after the new year started but then he decided to quit. Now it has been given to me.

The task is actually pretty simple, migrate that setup from the Hartmut’s old computer to a virtual machine. The task itself is just to automate the extracting of some data from MQ and writing to the file system with it’s original filename. The marketing guys will deal with the files after that.

I would rather use cron and bash scripts but that isn’t an option on Windows server 2008, so instead I will get to use the Windows task scheduler and a few cmd scripts.  The Windows scheduler is just as powerful and is standard for that platform.

Task scheduler (taskschd.msc)

Most of the task scheduler is pretty easy to guess.  The main tricks is to use a user that has admin privileges and to select run whether or not the user is logged in – well assuming that is correct for your situation.

Triggers

New trigger

Action

New action

     

I did my testing on windows 7 and the task manager works just fine if you have enough privileges.

 

Cmd Shell

My script doesn’t need to do more than setup a class path and call our Java program.  The output will be written to the current directory and pretty much everyone will be happy.

Well, almost everyone.  Not all that long ago one of our Unix test environments filled up with junk and I received a lot of status emails.  I don’t want something similar to happen on windows, and if it does, I don’t want it to be because of our log files.

In Unix or Linux I would be using the find command to gather up a list of files to delete, while on windows the cmd shelll has the “forfiles” command.

Just like the Unix find command, you can gather up the files by regular expression and/or age and then run a command for each file. This command will basically loop over all files in the given directory that matches the file specification or date.

@echo off
rem deal with old log files
set RUNLOGDIR=c:\logdirectory\runlogdir
 
set DELCMD=del
set LOGFILES=*.log
 
cd %RUNLOGDIR%
forfiles /p %RUNLOGDIR% /m %LOGFILES% /c "cmd /c %DELCMD% @path" /d -90

During testing you can replace the del command on line 5 with echo to see what would be deleted.  This was fairly convenient during testing.

I still am not a fan of Windows but it is obvious that they do have a lot of the same type of functionality as their Unix brethren.

 

Powershell

Windows also has the powershell interpreter which can also be used to create batch tasks. This might be a better choice than the old DOS cmd shell mainly because it is a true programming language that has a lot of functionality to allow easy access to the operating system functions.

It is just as easy to create very reusable function to delete files older than a given number of days.

# delete old files 
Function DeleteFiles([string]$DelPath,[string]$regexpr,[int]days) 
{
        # files older than xx days
        $cutoffdate = (Get-Date).AddDays(-days)

        $filesToDelete = Get-ChildItem -Path "$DelPath" -Filter $regexpr | Where-Object {$_.LastWriteTime -lt $checkdate -and !$_.psiscontainer}
        ForEach($file in $filesToDelete) 
        {
                Remove-Item  $DelPath$file -force
        }
}

This is a very nice solution that will be essentially self documenting when you add that function call to the rest of your powershell script.

ie

DeleteFiles c:\temp\logfiles *.log 15

There is a lot more information about powershell programming on the internet as well as are couple of my own blog entries

Windows scripting sucks or does it?

Windows powershell scripting

Reference information

Forfiles syntax

FORFILES [/P pathname] [/M searchmask] [/S]
         [/C command] [/D [+ | -] {dd/MM/yyyy | dd}]

Description:
    Selects a file (or set of files) and executes a
    command on that file. This is helpful for batch jobs.

Parameter List:
    /P    pathname      Indicates the path to start searching.
                        The default folder is the current working
                        directory (.).

    /M    searchmask    Searches files according to a searchmask.
                        The default searchmask is '*' .

    /S                  Instructs forfiles to recurse into
                        subdirectories. Like "DIR /S".

    /C    command       Indicates the command to execute for each file.
                        Command strings should be wrapped in double
                        quotes.

                        The default command is "cmd /c echo @file".

                        The following variables can be used in the
                        command string:
                        @file    - returns the name of the file.
                        @fname   - returns the file name without
                                   extension.
                        @ext     - returns only the extension of the
                                   file.
                        @path    - returns the full path of the file.
                        @relpath - returns the relative path of the
                                   file.
                        @isdir   - returns "TRUE" if a file type is
                                   a directory, and "FALSE" for files.
                        @fsize   - returns the size of the file in
                                   bytes.
                        @fdate   - returns the last modified date of the
                                   file.
                        @ftime   - returns the last modified time of the
                                   file.

                        To include special characters in the command
                        line, use the hexadecimal code for the character
                        in 0xHH format (ex. 0x09 for tab). Internal
                        CMD.exe commands should be preceded with
                        "cmd /c".

    /D    date          Selects files with a last modified date greater
                        than or equal to (+), or less than or equal to
                        (-), the specified date using the
                        "dd/MM/yyyy" format; or selects files with a
                        last modified date greater than or equal to (+)
                        the current date plus "dd" days, or less than or
                        equal to (-) the current date minus "dd" days. A
                        valid "dd" number of days can be any number in
                        the range of 0 - 32768.
                        "+" is taken as default sign if not specified.

    /?                  Displays this help message.

Examples:
    FORFILES /?
    FORFILES
    FORFILES /P C:\WINDOWS /S /M DNS*.*
    FORFILES /S /M *.txt /C "cmd /c type @file | more"
    FORFILES /P C:\ /S /M *.bat
    FORFILES /D -30 /M *.exe
             /C "cmd /c echo @path 0x09 was changed 30 days ago"
    FORFILES /D 01/01/2001
             /C "cmd /c echo @fname is new since Jan 1st 2001"
    FORFILES /D +14/2/2017 /C "cmd /c echo @fname is new today"
    FORFILES /M *.exe /D +1
    FORFILES /S /M *.doc /C "cmd /c echo @fsize"
    FORFILES /M *.txt /C "cmd /c if @isdir==FALSE notepad.exe @file"

Posted in programming | Tagged , | Leave a comment

lo-resolution fun – setting up a minecraft server

I remember playing computer games on 640×480 resolution and it was a lot of fun. Computer graphics has now improved to the point that some of the games are virtually photo-realistic.

With all of this in mind it didn’t make any sense to me when my son asked for Minecraft.  I tried to be a good parent and tested it out on my sons tablet.  It took me about 5 minutes to get bored and stop testing.  It just wasn’t my cup of tea to create my own buildings and dig holes in the ground but it seemed harmless enough.

For reasons I cannot fathom Minecraft was a instant hit with both boys.  The only thing was that all of their buildings ended up on one tablet which was inconvenient if both didn’t want to play at the same time.

Of course they also found some other Minecraft servers on the internet which allowed them to do some shoot’em up in teams.

Closing the stable door after the horse has bolted

It would be nice if the boys built their own villages and cities here on my server where it would be easier to control.  Shoot’em up games didn’t hurt me but I think the creative mode where you can build your own world is more interesting.

Installation of Minecraft

Microsoft has made the process of installing and running your own server painless.  The task is as simple as download the jar file and run it.  To make things simple Microsoft tells you exactly how to run the jar file.

java -Xmx1024M -Xms1024M -jar minecraft_server.1.12.jar nogui

The current version of the Minecraft server is 1.12 and requires java 8.

The last parameter is so the gui is not started when the server is started.  Once the server is started it is essentially a command shell.  From this point it is possible to change various aspects about the world, summon additional creatures or even grant operator status to any of the players.

Minecraft commands

There are a lot of commands for controlling the Minecraft world.  It is literally beyond the scope of what I can research and document about Minecraft, here is a small sample of some of the commands that I thought were fun.

Name Description
/time set <int> A day is equal to 24000 ticks where daytime is 1000 and nighttime is 13000.
/time set [day|night] Sets the world time to daylight or night time.
/weather [thunder| clear|rain] This will change the weather to one of the three states.  A fourth state is snow.  Snow only occurs if it is raining and you are in a winter area.
/summon sheep x y z This will summon a sheep to the x,y,z coordinates in the world.

Note: you can get your coordinates from your map.

It was fun to do these commands when my son was playing Minecraft mainly because of what I heard from the other room.

I am sure that there are a lot of sites that fully describe and list these commands.  The one that I used to find these commands was digminecraft.com.

Upgrade of Minecraft server

The upgrade process is simply to shutdown the server, download the new file and then startup the server with the new jar file.

 

Posted in Setup From Scratch | Leave a comment

Maven simple example

Maven was briefly described in my previous post.  In this post I will do a few small examples for actually using Maven.

One of the main things about Maven is the idea of the artifact.  The artifact is a file, which is usually a jar file.  This might be a jar that is a dependency or a jar, war or ear file that is generated by Maven.  All artifacts are described by three different key values.

  • artifactId
  • groupId
  • version

The artifactId is just a name.  The group id is also just a name but it is usually it is the reverse domain of the company.  The version number is just the version of that particular object.

Hello world – manual

The directory structure is fairly simple.  The program code will be under the src/main directory structure while the unit tests will be under the main/test directory.

mkdir helloworld
cd helloworld

mkdir src
mkdir src/main
mkdir src/main/java
mkdir src/test
mkdir src/test/java

The structure is simple but must be strictly adhered to.  The structure is well defined so the project object model (pom) file doesn’t need to contain much at all.

<project>
  <modelVersion> 4.0.0</modelVersion>
  <groupId> de.acmesoft </groupId>
  <artifactId> helloworld </artifactId>
  <version> 1.0.0 </version>
</project>

It is important to have the artifact keys in the pom file and they should be different than any other artifact keys.  This is important in case this artifact should end up in the repository.

The modelVersion field is refers to the internal structures for Maven.  In future releases of Maven this version may change.

The executable from Maven is mvn.  Simply pass in the phase that you are interested in and Maven will execute the lifecycle up to that point.

For this sample I could simply compile the class files or go one step further and generate a jar file.

#: /tmp/mvn mvn compile 
[INFO] Scanning for projects...
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] Building helloworld 1.0.0
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-resources-plugin:2.3:resources (default-resources) @ helloworld ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory /home/dock/working/content/43-blog/maven/helloworld3/src/main/resources
[INFO] 
[INFO] --- maven-compiler-plugin:2.5.1:compile (default-compile) @ helloworld ---
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] Compiling 1 source file to /home/dock/working/content/43-blog/maven/helloworld3/target/classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.974s
[INFO] Finished at: Sun Dec 11 23:27:27 CET 2016
[INFO] Final Memory: 10M/119M
[INFO] ------------------------------------------------------------------------

Running hello world

Maven creates all of it’s output files into the target directory.  This is true for both the normal class files as well as the jar files (for simple java programs) that get created.

If you want a quick test simply set the class path to point to the new jar file.

java -cp target/helloworld-1.0.0.jar com.acmesoft.helloworld

If you look closely at the pom file above you will see that it is inconsistent from the pom file. The package in the source code actually does reflect the test command.  At the end of the day, the code will indeed have the final say.

package com.acmesoft;

public class helloworld
{
  public helloworld()
  {
     System.out.println("hello world!");
  }

  public static void main (String[] args)
  {
     new helloworld();
  }
}

Hello world – template

In my opinion the most convenient feature of Maven is the ability to create an empty project.  There is a list of thousands of different types of template projects.  With a simple command it is possible to create the entire project from scratch – just add code.

mvn archetype:generate -DgroupId=de.acmesoft -DartifactId=helloworld -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false                                                                                                               
[INFO] Scanning for projects...                                                                                                       
[INFO]                                                                                                                                
[INFO] ------------------------------------------------------------------------                                                       
[INFO] Building Maven Stub Project (No POM) 1                                                                                         
[INFO] ------------------------------------------------------------------------                                                       
[INFO]                                                                                                                                
[INFO] &gt;&gt;&gt; maven-archetype-plugin:2.4:generate (default-cli) @ standalone-pom &gt;&gt;&gt;                                                     
[INFO]                                                                                                                                
[INFO] &lt;&lt;&lt; maven-archetype-plugin:2.4:generate (default-cli) @ standalone-pom &lt;&lt;&lt;                                                     
[INFO]                                                                                                                                
[INFO] --- maven-archetype-plugin:2.4:generate (default-cli) @ standalone-pom ---                                                     
[INFO] Generating project in Batch mode                                                                                               
[INFO] ----------------------------------------------------------------------------                                                   
[INFO] Using following parameters for creating project from Old (1.x) Archetype: maven-archetype-quickstart:1.0                       
[INFO] ----------------------------------------------------------------------------                                                   
[INFO] Parameter: basedir, Value: /tmp                                                                                                
[INFO] Parameter: package, Value: de.acmesoft                                                                                         
[INFO] Parameter: groupId, Value: de.acmesoft                                                                                         
[INFO] Parameter: artifactId, Value: helloworld
[INFO] Parameter: packageName, Value: de.acmesoft
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] project created from Old (1.x) Archetype in dir: /tmp/helloworld
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.132s
[INFO] Finished at: Sun Dec 11 23:46:15 CET 2016
[INFO] Final Memory: 13M/223M
[INFO] ------------------------------------------------------------------------

The generate command not only creates the directory structure but also creates the pom.xml file.  You can see how the command line parameters end up in the appropriate location in the pom file, which is also created automatically.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.acmesoft.secondexample</groupId>
  <artifactId>secondexample</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>secondexample</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency> 
  </dependencies>
</project>

This pom file is actually also a very basic file.  The very minimum is the same as the manually created pom file in the manual section.    Maven automatically added Junit in order to allow the unit tests that it also created to compile.

package de.acmesoft;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

/**
 * Unit test for simple App.
 */
public class AppTest 
    extends TestCase
{
    /**
     * Create the test case
     *
     * @param testName name of the test case
     */
    public AppTest( String testName )
    {
        super( testName );
    }

    /**
     * @return the suite of tests being tested
     */
    public static Test suite()
    {
        return new TestSuite( AppTest.class );
    }

    /**
     * Rigourous Test 🙂
     */
    public void testApp()
    {
        assertTrue( true );
    }
}

The template also includes the source code for our hello world program as well.

package de.acmesoft;

/**
 * Hello world!
 *
 */
public class App 
{
    public static void main( String[] args )
    {
        System.out.println( "Hello World!" );
    }
}

One small difference between the manual project that I created is that using the template creates the package, the pom file and the directory structure all consistent with each other.

Hello world – log4j

The generic hello world prints the output to the standard output and doesn’t use external libraries for any task.  Some applications or utilities might be this simple but it is uncommon for any but the most trivial application to not use external libraries for some purpose.

To simulate such a case, I have modified the hello world application to use log4j for all output.

package com.acmesoft.secondexample;

import org.apache.log4j.PropertyConfigurator;                                                                      
import org.apache.log4j.Logger;                                                                                    

public class App                                                                                            
{                                                                                                                  
  public App()                                                                                              
  {                                                                                                                
     String cfgFileName = "log4j.properties";                                                                      
     PropertyConfigurator.configure(cfgFileName);                                                                  
     Logger logfile = Logger.getLogger(App.class.getName());                                                
                                                                                                                   
     System.out.println("hello world!");                                                                           
     logfile.info("hello world");                                                                                  
  }                                                                                                                
                                                                                                                   
  public static void main (String[] args)                                                                          
  {                                                                                                                
     new App();                                                                                             
  }                                                                                                                
}

Running hello world

My first test of the application failed for obvious reasons.

java -cp target/helloworld-1.0.0.jar com.acmesoft.secondexample.App

The reason was NoClassDefFoundError was thrown.  The application uses log4j so it will not work unless it is part of the classpath.

java -cp target/secondexample-1.0-SNAPSHOT.jar:lib/log4j-1.2.17.jar com.acmesoft.secondexample.App

Maven is just another way to compile an application, the Java basics don’t change.  Simply make sure that when running the program that all necessary dependencies are provided. However, Java programs cannot be compiled unless the code that it is dependent on are provided. This is done by adding dependencies to the pom file.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.acmesoft.secondexample</groupId>
  <artifactId>secondexample</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>secondexample</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>2.0.1</version>
    </dependency> 
  </dependencies>
</project>

The dependencies block contains both a dependency for JUnit and Log4j.  The JUnit dependency was automatically added when the application was created by Maven (in order to support the automated testing) but I manually added the Log4j block as it would be necessary for the program.

Hello world – log4j revised

The good news is that Maven can be configured to include the dependencies as part of the “package”.  This way it is possible to create the equivalent of a statically linked application that can simply be copied from directory to directory and it will still work.

The list of dependencies don’t change but what does change is the new “build” block that embeds the dependencies into the resulting jar.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.acmesoft.firstexample</groupId>
  <artifactId>firstexample</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>firstexample</name>
  <url>http://maven.apache.org</url>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.17</version>
    </dependency> 
  </dependencies>

  <build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>2.1</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <transformers>
                            <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                <mainClass>com.acmesoft.firstexample.App</mainClass>
                            </transformer>
                        </transformers>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

</project>

Once the dependencies are embedded inside the jar file, you can simply run the application without worrying about the rest of the dependencies.

java -cp target/firstexample-1.0-SNAPSHOT.jar com.acmesoft.secondexample.App
Posted in programming | Tagged , | Leave a comment

creation of a more responsible padlock

I have been cleaning up my flat in preparation for the move when I ran across a few small TSA locks.  Sure I have used them when traveling to and from the United States but it certainly seemed to be a pretty sketchy to keep your things safe.

Oh, sure it must have seemed like a good idea when it first came up in that meeting.

Why don’t we require all the passengers use locks that we have keys to.  It would make it a lot easier if we need to search a suitcase that looks questionable.

I suspect it might indeed make things faster if there is a key-chain on the wall with the master keys for all of the locks.  I couldn’t find any statistics on how many suitcases are opened every year but I suspect that despite the number opened the percentage is pretty small compared to the 432 million scanned.

It does actually make a lot of sense having these master keys as some traveler might be trying to smuggle money, drugs or art artifacts in their suitcase.  These activities are all illegal and most law abiding people would agree that the law should be obeyed the criminals should be caught and punished. Right?

The only problem with that is that scenario is that people are only human and some of the species are drawn to taking short cuts in order to achieve their goals.  Some people might even be using their position to get copy of such a key.  The security on these keys is (hopefully) very tight but it is not necessary enough to prevent someone from stealing a key.

People can be greedy or unscrupulous but they also have another attribute – sometimes they are sloppy.  Just like accidentally saying to much to a boss or a friend, during an article on TSA travel security, a picture was published of these master keys.

I am not a locksmith but it apparently just a hop skip and a jump from a photograph of a key to creating a physical key of your own.

So while it might seem like a good idea at first to have a number of different TSA padlocks and have the authorities control the keys it really isn’t. Humans find it is pretty much impossible to keep a secret and have a very hard time with good operational security.

Despite having a limit number of locations where these locks will be used there is a market for making bootleg keys available – even years after the key leaks.  Possible to purchase keys for these master locks on ebay.

I am not really interested in the TSA locks.  I am giving serious consideration to simply purchasing any old lock and using it.  There will be two outcomes.  The first is that my suitcase will not be selected and thus the lock doesn’t make a difference.  The second is that my suitcase is selected and they discover that I am using a non-TSA lock.  They will just cut it off and go about their business.

Both of these options would make me more secure than having a lock that virtually anyone could open (pilfer things from my suitcase) and then lock it up like nothing ever happened.

Not physical locks but Encryption

The record with physical security isn’t so rosy but it seems considerably more secure than in the electronic world.  It seems like not a month goes by without some sort of huge data breach being published.

This isn’t talking about using “responsible encryption“, this is simply talking about how poor the current state of electronic security is.

These breaches of occurred just because the “bad” guys go where the data is.  This level of data protection is not acceptable but unfortunately this seems to be the norm.

This is the track record of companies whose livelihood depends on staying in business based on their appropriate control of customer data.

With this track record, does it seem like a good idea to hand over the keys for everyone’s electronic key to the government?  Well, it is the government, perhaps they are better at keeping control of their data.

It is possible to attempt to change the behavior of people or countries by changing the laws. Right?

Responsible Encryption

It has been suggested, yet again, that there is some possible way to both have safe encryption and yet allow the government easy access to it whenever they want.

The other problem is that humans are a really tricky lot and can come up with a number of clever solutions other than normal encryption.

It is not clear if the US president does intend to pressure companies to use breakable encryption or encryption with backdoors but it would probably have unexpected consequences.

The harder naughty people are chased, the further from the common methods of communication they will stray.  If phone encryption is no longer safe, they will brew their own.  If that is not possible some of these other historic encryption methods may be used in the dark corners of the internet.

Responsible encryption is strong encryption.  In my opinion, it is criminal to weaken encryption that will inevitably end up not only in a social app, banking app or perhaps password keeper.  Securing peoples personal information in this age of no privacy is being safe and responsible.

Finally I did see a response to this article that pretty much sums up the hypocrisy of a Republican president wanting more control.

Beyond all the absurdity of this all is the fact that the party that’s been yelling about “limited government” for decades is now suggesting a central government entity collect the passcodes to everyone’s data “just in case”.

– Ihave8eggs

In the United States it is not uncommon to see a bumper sticker.

When guns are outlawed only outlaws will have guns

This may be true for something physical like weapons but it is even more true for encryption.  The genie has been let out of the bottle decades ago and it is not possible to put the genie back into the bottle.  This is because strong encryption is no longer only in the realm of governments.  It is possible to download open source solutions that are just as tough to crack as something the NSA uses.

This is the problem that law enforcement faces.  Your dirty little secrets on your smart phone are probably as secure as the data stored at Langley.

Posted in Soapbox | Tagged , , , | Comments Off on creation of a more responsible padlock

Maven the alternative build tool

Why maven

Maven is a tool for building software. Doesn’t there already exist a number of tools for doing this exact task?  Two different tools that do this are the classic make utility or the much newer Apache Ant.

The make utility requires a script that defines all of the objects and their dependencies. Make forces you to define every object and their dependencies.  That is a bit of a harsh analysis of the make tool as it is possible to create more generic rules for compiling objects from source but in general this is accurate description of make.

Apache Ant is a few more steps along the automation path from make.  You define some of the targets and a few rules in your build.xml file for compiling code, making jar files or other general commands.  There is no default defined directory structure for the source files or external libraries.  You need to define the structure each time you create a new program.

Maven has a number of differences from other build tools.  There is a very specific directory structure for each of the types of programs or objects that Maven can build.  In addition to the actual directory structure Maven has the concept of a the software lifecycle for the objects it builds.

Maven will perform all the steps in the lifecycle from the start up until the phase that you select.

  • validate – perform a check to ensure that all the necessary files are available.
  • compile – compile the source code of the project.
  • test – runs the unit tests that have been defined.
  • package – create the final package for the code.  This might be a JAR, WAR or EAR file.
  • install – install the package into the local repository.
  • deploy – install the package into the remote repository.

Thus the program is compiled before it is tested and tested before it is packaged.

It is possible to setup a similar flow using Apache Ant but then you are responsible to create lifecycle from scratch.  This includes adding additional logic for doing testing and implementing logic for installing the compiled objects.

In addition to all the other built-in logic that Maven contains it also is well aware of the different types of output objects such as jar or war files.

Maven Repositories

Another major difference between these other tools is that Maven has its own repository of jar files and other artifacts that might be needed when building objects.  Maven can store multiple versions of the various artifacts in its repository.

The central repository is full of all sorts of open source jar files so it is quite possible that if your project uses one of these jars (ie log4j) then it will already be available.  You simply add your required dependency and it will be downloaded to your computer and used on the next build.

Each object in the repository is defined by the unique combination of three different keys.

  • groupId
  • artifactId
  • version

The combination of these three keys creates a unique value that refers to the object specifically.  This built in repository concept actually really simplifies dealing with libraries if you only need open source libs.

Of course it is also possible to add other third party libraries.  Using libraries that are not already in the repository is a bit different and will be described later.

Projects and project structures

One of the advantages to Maven is the structure that it provides.  Maven contains a lot of templates and standard directory structures.  There is a structure available if you simply need to create a java jar file but there is also a template if you want to create restful web applications.

Of course, it is possible to create these directory structures manually but another feature of Maven is that you simply pick which type of project you wish and it will create the entire directory structure for you.

Testing your work

It goes without saying that providing unit tests would be both a best practice and is easy enough to do if you start at the beginning.  Performing the unit tests is part of the lifecycle and because they are run before creating any packages it should help to guarantee a higher quality of program.

Summary

Maven is a enterprise quality build tool that supports more than just the generation of programs or libraries.

Maven is big but I will attempt to describe some of the basics for anyone who wishes to expand their tool set to include it.

 

Posted in programming | Tagged , | Comments Off on Maven the alternative build tool

installing maven on linux

Maven offers quite a bit as a enterprise build tool.  It can help ensure that standards are followed and offers support for automated testing.  This tool is actually really simple to install.  It is just a matter of unpacking it and adding it to your path.

This is described on a lot of locations on the internet.

https://intojava.wordpress.com/2016/05/05/install-maven-linux-mint/

The nice thing about most of the major linux distributions is that most major packages provide a package to install Maven.  This takes care of both the installation and setup of the path.

However, in my test this also installed a lot of other java packages that should not have been necessary.

apt-get install maven
Posted in Command line, Setup From Scratch | Tagged | Comments Off on installing maven on linux

command line fun – finding mistakes

I knew that I had mistyped but it was too late.  I tried to exit out of vi in a hurry and accidentally exited but saved the file under a new name.  This wouldn’t have been so bad if the new name didn’t consist of a single control character.

My fears were confirmed when I did a directory listing.  Not only did it make an annoying sound but you could see in the file listing that the files were no longer lined up.

This isn’t the first time that my fingers got the better of me, so I simply ran the ls command and asked that it display the inode number of each of the files.  Normally that would have been fine but my control character, perhaps ^H, was actually removing the previous character displayed.

This means that my inode number was any one of ten possible values.  There are other ways to try and determine exactly what inode number a file is but before trying that I simply did a long listing using ls.

This actually did show that my inode number was 540.  I am actually a bit surprised that you cannot use this information directly to delete the file with the rm command (on Solaris, also on Linux?)

This information however can be used in conjunction with both the find and rm commands to delete this tiny mistake.

Instead of the familiar -name option for the find command there is a somewhat less used   -inum option.  As this option name implies, it will look only for files that have this inode number.

Once it is possible to find the actual file it is a simple matter of using the -exec option of find to remove the file.

find . -inum 540 -exec rm {} \;

Extra credit method

There is another way to find an inode number using just variations of the find command.

find . -name “*”  -ls

This will just do a directory listing of the files under the current working directory and run a similar directory listing at the same time.  Deleting the file is done using the same find and remove as described above.

Posted in programming | Tagged , | Comments Off on command line fun – finding mistakes

Got a new tablet for the price of fastfood meal …

… well, that is a bit of an exaggeration.  I owned a Samsung Galaxy S tablet which no longer worked.  It had the darndest symptoms.

  • doesn’t charge past 77 %
  • takes a day to get to 77%
  • spontaneously restarts shortly after startup

The plan was to take the tablet apart and try and repair it (despite not being a certified hardware repair person)  After all, just how hard could it be?

The repair

The tablet wasn’t that old and was in otherwise perfect condition.  The Internet implied that there were a couple of different parts that might solve the problem.  I was hoping that simply replacing the usb port would be the problem.

https://www.amazon.de/gp/product/B01MFH19ZY/ref=oh_aui_detailpage_o02_s00?ie=UTF8&psc=1

It would have been perfect, the cost for a new port is less than 6 Euros.  There are a number of really good youtube videos to help for replacing the usb port  or how to replace the battery.

The hardest task was actually getting the back of the tablet off.  The video for replacing the usb port makes it look pretty easy.  In that video the back itself is simply pulled off and you don’t need any special tools for that.

It might be obvious from this picture but when I removed the back I actually pulled the screen out from the other side. This is actually quite similar to how it is removed in the battery video.

Removing the charger port is actually trivial, especially if you have removed the screen in the way that I did.  The reason is that the back of the tablet is actually two parts.  The first is a rim that goes around the tablet and holds both the screen in from one side and the back from the other side.  This rim actually would make it a bit more difficult to get the port off.

Near the usb connector port is a two screws that hold the port to innards.  Once the screws are removed a small bit of pressure and the port and the sdcard hold pop right off except for a small connector that also attaches to the board.  The other end is a flat cable.  The connector is slightly different as it flips up rather than slides to release the cable.

I had hoped that this six euro part would fix the problem but as it turned out this did not solve my problems. The new port did appear to work but once I removed the power cord from the tablet the device would barely make it to the startup screen.

https://www.amazon.de/gp/product/B00R1A0VK6/ref=oh_aui_detailpage_o00_s00?ie=UTF8&psc=1

The battery is actually even easier to remove than the charging port.  There are four screws that held it in place and then the power cord snaps onto the board.

Lessons learned

Dealing with the insides of this particular tablet was actually very easy to work with.  The most difficulties that I had was trying to get the cover off.  I think that I must have been looking at a different video and it didn’t make the task easier.

I actually had a small set of tools that offered a number of possibilities but I used the small triangular pic.

The correct tool appears to have been this tool that I happened to overlook.

Everything works

For the low low cost of about 38 Euros I managed to get my tablet to work.  I wouldn’t have done tried to take this apart if it hadn’t been non-functional and out of warranty. I don’t know how the repairable the newer Samsung tablets are but the older ones appear to be very repairable.

Posted in Setup From Scratch | Tagged | Comments Off on Got a new tablet for the price of fastfood meal …