<![CDATA[JWrapper - blog]]>Thu, 15 Nov 2018 06:24:27 -0800Weebly<![CDATA[Easy Beta and Developer builds]]>Wed, 11 Jan 2017 14:39:09 GMThttps://www.jwrapper.com/blog/easy-beta-and-developer-buildsWith our new release today we introduced a number of features but the first we'll cover today is alternate builds.

Because JWrapper packages your java app in a consistent way and handles all the hassles like icons, app names, executable names, installation folders and elevation, we've been able to add a simple switch that lets your app deploy as a completely separate installation with its own name, versions and storage areas.

As of today's release just adding these options to the end of your JWrapper build:

-altBundle <suffix>
-altUrl <url>


will change the naming and installation of your app to reflect the added suffix (e.g. "Beta" or "Dev"). 

This allows you to run the production version of your own app (always useful for support purposes or maybe you just find your own app useful) alongside a developer version for testing and debugging.  

It also allows you to very easily create a beta version and to distribute your beta version to customers and have them run it while keeping the production version around to use for critical work.  They can install, upgrade, break, delete the beta version without ever affecting the production version of your app.

The alternate URL specifies an alternative Update URL allowing you to run beta or alternate versions with their own timelines and release cycles - for example a regularly updated beta build.

]]>
<![CDATA[High privileged time and exceptions - important Java JVM options you should consider´╗┐ if running a server]]>Thu, 21 Jul 2016 11:02:56 GMThttps://www.jwrapper.com/blog/high-privileged-time-and-exceptions-important-java-jvm-options-you-should-consider-if-running-a-serverRecently we were working with a server that was handling a relatively modest number of TCP connections (low hundreds), some of which were handled as TCP and some which were HTTP.  

The nature of this server was that it handles the raw TCP connections with a number of threads, multiplexing data in and out of the streams, using locking to control access in various ways.  In the normal case the server was using around 10% CPU with periods of higher CPU time during 'failover' (switching all connections to a secondary server) or of high concurrency (lots of new connections coming in).

During these times of high load though we sometimes saw a strange phenomenon:

High CPU usage is expected for a short time during these periods but this was something quite different.  The CPU in the above chart is being pegged at 100% for long periods - sometimes minutes - and the proportion of privileged time (kernel time) is very high.

Even more strange then that during this time the server seemed to be doing very little.  Few if any printouts to the log, connections to the server appeared to be being starved and would report an error, what could be happening during this time?

Garbage collection - not always the culprit

The most obvious culprit for this type of high CPU usage that seems orthogonal to the programs operation is garbage collection.  Having the JVM dump GC logs showed some GC and safepoints around the pauses sometimes but it wasn't a good match.  In addition a test program we wrote to provoke GC couldn't get it to pause for such long periods or use high privileged time doing it.

​In this case at least, GC wasn't the issue. 

Safepoints and sampling profilers that can't sample

The obvious first step here is to fire up a profiler and look at what is consuming all that CPU.  A Java profiler can typically be constructed in one of two ways - sampling or measuring times.  If you've encountered the basic java HPROF profiler you may know that samples or times are an option for CPU profiling but aside from HPROF the vast majority of profilers available for Java are sampling profilers.  These profilers pause the JVM often and take a snapshot of what is happening.  They then collate their samples and present it as a representative picture of what is going on in the JVM.

Unfortunately these profilers can sometimes have a hard time getting the snapshots at the point where they want them. One profiler we ran over a 1-minute high-cpu time for example managed to gain all of 2 snapshots, then happily presented the results that BigInteger was the cause of all our high CPU.  Sadly these snapshots both happened after the fact pause and gave only a brief look into what the server was doing in recovering connections after the hang. 

For a more complete rundown on the problems with sampling profilers take a look here.  A better sampling profiler can use OS signals to interrupt and break into a JVM at a given point and capture information without having to wait to be given time within the JVM but in our case even this didn't work because the kernel time was too high and the OS wasn't even responsive to signals.

Privileged time and kernel APIs

Having struck out on profilers, we knew that high privileged time in Java narrows the issue down to a subset of possible cases.  A number of threads in infinite loops in Java will send the CPU on a multicore system to 100% but it won't use privileged time, instead it will be almost entirely composed of user time cpu (app cpu usage, not the OS kernel) and it also generally won't starve the entire computer of the ability to do anything other than very high priority tasks.

Drivers and other low level OS bits of code can produce privileged time and a buggy driver can often be a candidate for high privileged time cpu usage so this was our next port of call.  Installing driver updates didn't help so we switched to kernrate which helped us narrow it down some more, specifically to one module - NTOSKRNL.

Kernrate also showed some CPU usage in the network driver module but the vast majority was in the above one, unfortunately thats probably the widest possible one since NTOSKRNL is the entire Windows NT OS Kernel.  Kernrate did report more specific information on the functions where the issue occurred but the functions were generic enough to not point the finger at a specific bit of code - KeSynchronizeExecution and ExReleaseRundownProtectionCacheAwareEx.

The kernel only offers a certain set of APIs though, so the issue has to be in one of those.  Typically this might be something like:
  • Paging
  • Disk I/O
  • Network I/O
  • Interrupts and exceptions
  • Other functions that you might find in the Windows API

A typical Java program will do most of its work outside of these but a server in particular might be expected to use some of them quite heavily.   Looking at the specific functions in the module with kernrate didn't show much.  The functions that kernrate identified don't tell us much but they do point to something to do with interrupts.  

At this point we started monitoring a bunch of metrics during the pauses.  Perfmon also suffered from starvation during the pause but running it in high priority allowed us to grab some metrics and showed that paging and disk I/O weren't to blame but that we were getting a spike in packets per second under TCP/IP v4.  

Packets per second

Finally we had our theory that fit the data - the number of packets per second was spiking perhaps due to a new connection coming in or multiple at once, then with enough new connections coming in simultaneously the packets per second would accumulate and use up a lot of kernel time while they were processed.​

Modern OSes can handle a lot of data flowing through them and in our case the amount of data being moved around was relatively small - under 2MB/sec - but packet processing isn't the same as bandwidth.  Instead, packets coming into your network adapter produce an interrupt - they block the CPU from doing whatever its doing and ask it to process the packet that just came in.  The same process occurs for your keyboard and mouse which is why they can stay responsive even when your computer is working hard.

​We found and fixed the issue, re-ran our test, saw that the packets per second remained low, and then saw the same huge privileged time and long pause.  Packets per second weren't the cause of our problems after all.

Exceptions and JDI

The next metric we managed to find a correlation with was System Exception Dispatches per second.  A bit of reading about Windows internals didn't turn up a lot of information but it did highlight that exceptions would be something that would only happen in response to something the app was doing, not happening at random points as you might expect from an interrupt for a network packet appearing.  
At this point we fell back to creating our own non-sampling profiler that would give us limited information but would at least work in a way that was sure to capture information around the problem area.

Java profilers are often sampling profilers because by doing sampling they limit the impact they have on the running program, allowing it to run much like before.  Measuring profilers take a different approach - measuring the entry and exit times of at least a subset of method calls occurring in the JVM.  This is a vastly more computationally expensive method and although the profiler was producing better information the issue was impossible to reproduce given the slowdown caused by monitoring methods with either JVMTI or JDI.  Both of these are great APIs for creating your own fine tuned profiler and allow you to do so in pure Java.

That said JDI did at least allow us to monitor Java exceptions without a massive slowdown.  Although we did see Java exceptions around the problem period they didn't correlate.  The number of windows exceptions being generated were many orders of magnitude higher than ours - hundreds of thousands per second.

JVM bugs - don't forget to -XX:+UseMembar

The last place we looked was the last place we wanted to look - in the JVM.  Building OpenJDK on windows allowed us to debug the exception handling directly in the JVM and turned up an issue with write_memory_serialize_page, with many thousands of exceptions being thrown per second during the pauses.

We eventually worked our way through to this JVM bug and this duplicate.  

​Closed as fixed in Java 6 but apparently back with a vengeance in Java 7 and 8, Java's 'pseudo memory barrier' optimisation somehow erroneously results in a pauseless loop of generated windows exceptions.  This can lock up the computer in useless high priority exception handling for minutes at a time preventing almost anything else from running, yet can be disabled with a single simple JVM option:

-XX:+UseMembar

With this option enabled our JVM went back to running our server smoothly and almost zero windows exceptions thrown, even with large simulated concurrency spikes in connections:

While I can't say I enjoyed our extensive debugging travels in this case it was an interesting look into the depths of Windows and the JVM and ultimately resulted in a much smoother running server.

​Do you run a Java server or app and have a list of JVM options you always make sure to use?
]]>
<![CDATA[Avoiding System.currentTimeMillis timing errors when the OS clock changes using JWConstantClock´╗┐]]>Fri, 06 May 2016 15:57:38 GMThttps://www.jwrapper.com/blog/avoiding-systemcurrenttimemillis-timing-errors-when-the-os-clock-changes-using-jwconstantclockOften when programming it can be necessary to have one or more threads sleep for a specified period of time.  A common case for example would be a program which needs to execute code at a set frequency.

Games for example might need to draw regularly updated frames on the screen.  Drawing frames as fast as possible would mean chewing the CPU (or one core at least) and potentially wasting resources on the machine not to mention power, while perhaps drawing at a framerate way beyond anything necessary for smooth motion.  A simple solution to this is to take the time of the previous frame, perform any updates and then calculate how long the sleep should be to hit exactly 50 frames per second.

But what happens if the user, or an automated part of the OS syncing time with a time server (standard on most modern operating systems now) changes the clock between frames while the program is sleeping?

System.currentTimeMillis in Java offers the standard time measurement of milliseconds since 1970, but changing the clock on the operating system will change the value of System.currentTimeMillis.  When the program wakes up if this potential (but not easily knowable) change has occurred it may calculate that it has overslept or underslept hugely.  In this example if we assume the clock has been adjusted back five minutes, then depending on how the timing is implemented the program may calculate that it needs to pause for 5 minutes (and maybe a few milliseconds) to reach the next frame.  Suddenly and without explanation the app or game has paused and the user is left scratching their head.

​JWrapper now provides a utility class to avoid this issue entirely by having a clock that still returns precision in milliseconds but is kept (as closely as possible) constant over any clock changes.  This allows you to write timing code anywhere without having to worry about clock changes interfering with your code and introducing either long unexpected delays or periods of unexpectedly very high rates.

For more details check out the class javadoc in the JWrapper Utility APIs.
]]>
<![CDATA[New JWrapper release with big improvements to the JWrapper App]]>Wed, 20 Jan 2016 17:54:24 GMThttps://www.jwrapper.com/blog/new-jwrapper-release-with-big-improvements-to-the-jwrapper-appWe have a new JWrapper release out today fixing various bugs and issues people have reported over the past few months.

Also today we have a new version of the JWrapper app including a lot of big improvements.  The app now supports a wider range of JWrapper features including paid features, makes the project model much more simple and easy to understand, and provides more guidance for new users.

Head over to our download page to upgrade or try it out today:
]]>
<![CDATA[Launching your Java app from the command line or from another Java app]]>Fri, 08 Jan 2016 11:50:04 GMThttps://www.jwrapper.com/blog/launching-your-java-app-from-the-command-line-or-from-another-java-appJWrapper makes it easy for users to download and run your Java app by producing native executables for each operating system.  So in Windows your users are running a windows executable and in MacOS they are running a dot-app file.  

Ordinarily, had you compiled to native executables or bundled as an installer with another tool, you would lose some of the benefits of running in Java.  So if you wanted to load code via reflection that may no longer be possible, and if you wanted to download another app from your suite and launch it, you would have to write code specific to the operating system, test it thoroughly on a range of OS versions and handle the downloading and permissions yourself, taking care to build the launch command correctly and handle any parameters you needed to pass on.  There are many pitfalls with this unwieldy approach like command line parameter quoting and limits, handling elevation and directory permissions.

Since JWrapper itself both builds and operates in Java, you retain the benefits of running in Java, and we also make it really easy to download and run your app from within any Java code by giving you a simple API to do it.

There are some good reasons why you might want to do this, including:
  • You want to offer your JWrapper app as an add-on to other Java apps
  • You want to advertise within one app and make it super easy for the user to grab your other apps to try them out
  • Your suite of apps is large and you want to split them into multiple downloads, but still want to keep things simple for the user

In each of these cases you are already in Java, and want to launch another JWrapper app, meaning you can use JWrapper's simple API - JWCommandLineWrapper.

The JW command line wrapper is built when you build any JWrapper app and placed in your build folder under <AppName>-java-online.jar.  This jar contains the JWCommandLineWrapper class and can be used as a utility jar to launch other apps (if you're running from arbitrary Java code) or, if you are already using JWrapper the class will already be ready on the classpath and usable.

The jar itself can be run from the command line to allow installing your app, and the update URL can be specified to launch any app from any provider, for example:

java -cp HelloWorldApp-java-online.jar jwrapper.cmdline.JWCommandLineWrapper
java -cp HelloWorldApp-java-online.jar jwrapper.cmdline.JWCommandLineWrapper http://example.com/OtherAppURL


but for a much simpler and more flexible approach we can launch directly from Java by using the JWCommandLineWrapper class to either launch the default app it was built for, or launch any JWrapper app by specifying the JWrapper Update URL for that app:


    public void launchApp(String url) {

        JWCommandLineWrapper jwc = new JWCommandLineWrapper();


        //optionally override the URL from the default to a new one, allowing us to launch any JWrapper app
        jwc.overrideUpdateURL("http://example.com/MyOtherAppURL");

        //optionally override the virtual app to launch from the default to a prespecified one

        jwc.overrideApp("MyVirtualAppName", false, JWCommandLineWrapper.INSTALL_TYPE_CURRENT_USER);
        
       
//optionally pass in any launch properties to the virtual app (no need to worry about command line restrictions!)
        jwc.setLaunchProperties(lprops);

        //setup and update (if necessary) and then launch the app
        jwc.updateAndLaunchAppNow();
    }


This gives you the flexibility to manage your JWrapper bundles and apps however you want, without having to lose out on any usability for your user, or create any difficulties in development.

]]>
<![CDATA[New release and network utility APIs]]>Tue, 28 Jul 2015 11:32:58 GMThttps://www.jwrapper.com/blog/new-release-and-network-utility-apisWe have a new release of JWrapper out today with some helpful fixes and, even better, the beginnings a couple of new utility APIs.

Always in JWrapper we aren't trying to bring you bog standard code you could find anywhere on the internet with our APIs, instead we try to give you utilities we've found helpful from decades of experience in Java programming.  Utility APIs you may not even have realised you needed until you hit on some difficult to track down bug or weird behaviour.

The first of our APIs - JWSockets - allows you to do something which the standard APIs won't let you - track and debug all socket creation and disconnections within the JVM.  If you're unsure about how your URL queries are being handled, or you're writing a game and you want to be sure you aren't making any mistakes, JWSockets gives you a bunch of useful functions to see whats happening.

The starting point is to set up JWSockets to intercept all socket activity:

    JWSockets jwsocks = JWSockets.interceptSockets();

From there we can have it print all socket activity to the console:

    jwsocks.printAllSocketActivity(true);

Or we can have it retain a list of all live and closed sockets:

    jwsocks.retainLiveSockets(true);
    jwsocks.retainClosedSockets(true);


then get the lists, or the count of sockets in each state:

    getOpenedSocketCount()
    getClosedSockets()
    getClosedSocketCount()
    getLiveSockets()
    getLiveSocketCount()


or even add a listener to get notified whenever a socket is opened or closed in the JVM:

    addListener(JWSocketsListener)

The second API we've added is just the beginning of a new set of functions - JWNet.  Currently this has just one function which sets the HTTP agent for all HTTP queries in the entire JVM.

Again, if you've tried to do this before you may have found pretty simple code which appears to set the HTTP agent for your queries like this:

    System.setProperty("http.agent",myHttpAgentString);

But unfortunately what you might have missed is that although this does alter your HTTP agent string, it also appends 'Java' on the end.  If you want it to pick up and use the exact HTTP agent you specify throughout the JVM, you can use JWNet.

    JWNet.tryForceHttpAgent(myHttpAgentString);

]]>
<![CDATA[Automated testing for your Java app]]>Mon, 26 Jan 2015 19:58:56 GMThttps://www.jwrapper.com/blog/automated-testing-for-your-java-appDespite being a crucial part of producing a commercial quality app, testing is a part of development that is often dreaded or left lacking.  If you are lucky enough to have a dedicated test team then you can maximise developer time spent creating productive features and simultaneously maximise the testing and stability of your product.

If you have a smaller team though then testing will often fall to developers or other users within the company and can be a drag on other activities, leading it to often become neglected.

Manual testing vs Unit testing

Often stability can be improved in software by creating unit tests - bits of code designed to create an environment for some other code, feed it inputs and check it outputs.  For certain types of code these can be a great benefit and can pick up on a lot of issues before they even make it into a build.

For other types of code they are less feasible.  If the environment to be simulated is very complex or if the code is heavily reliant on other areas of the product then creating a 'fake' test environment may be a very complex job.   It may actually be easier to simply build and run the app, testing it live in its natural environment running on the OS.

Some example cases might be areas that involve a lot of user interface interaction or client-server interaction, or that require the app to be restarted and run in different configurations or interactions between multiple apps.

A fully programmable test environment

JWrapper's design has always been more than simply something to launch your app on the OS of your choice.  Instead it acts as an additional layer in your app's environment which provides your app with a broad range of new benefits.  APIs provided by JWrapper allow you to access native and non-native utilities that are not part of the JVM without having to worry about writing native code for Windows, MacOS and Linux (and test it).

Taking advantage of this, the latest version of JWrapper now includes facilities to allow you to automate the testing of your app, potentially even in live systems or on problematic customer sites.  

Your app bundle can now include a virtual app which can launch your app over and over with a test specification to run, or have it connect back to be controlled centrally, reporting everything into a test repository you can view live on a web browser.

A full OS environment as a test harness

The first part of this new API is the JWTesting class.  The idea behind this simple API is that you should first create a new virtual app which will act as a dedicated test-driving app. 

To prevent the user from launching it you can mark it as a non user-accessible virtual app.  To run it, you can use the simple command line parameter:

myapp.exe JWVAPP MyTestingVirtualApp

or you could have your own app transform into your testing app whenever you like by listening for keyboard shortcuts, then forking your testing app and closing itself:

JWSystem.forkVirtualApp("MyTestingVirtualApp")
...
System.exit(0);

This keeps testing invisible to the end user but allows you to fire up your full-environment test harness anywhere, even on a customer site to run some debugging.

Once your new virtual app is up, you can ask JWTesting to start a new test report server (by default it starts on port 5555), and then ask it to open you a browser to view the test results coming back:

JWTesting jwa = JWTesting.createReportServer();
jwa.openBrowser();

Your test app now has all the control points to launch, terminate and control your app to automate its testing.

Automating some simple usage

To run a simple automated test on your testing  virtual app you can start by asking JWTesting to set up some test properties for your normal app, then launch it:

Properties props = new Properties();
JWTesting.prepareTestInstance(props);
JWSystem.forkVirtualApp("MyVirtualApp",props,null);

When your normal app launches it will now automatically create a connection back to your test report server allowing it to report attempts and successes of anything it tries to automate.

Your normal app can check if its been launched to run tests by calling JWTesting.amTesting() and can use JWTesting to report attempts and successes:

reportAttempt(String name, String details, int timeoutFailMillis)
reportSuccess(String name);
reportFail(String name, String details);

Attempts automatically fail after the timeout expires catching even severe errors that you didn't anticipate (like the app exiting or crashing).

It can then look out for any instructions sent through in the dynamic properties file to see what it should try to simulate.  As it simulates user interactions (using another API we provided, mentioned later), it can report attempts, successes and failures back to your test server.   These are then handled by your test server and appear in the browser window as a colour-coded list:

If you do have a failure in your app, JWrapper will automatically take advantage of its position as a wrapper around your app to grab a log file for your app at the time the failure was reported, send a copy back to the report server, and it will then be posted to the browser list to let you view the logging around the error, even while the test is still running:

Pushing buttons, like a real user

All these APIs are very useful but even after your app has launched in its natural environment and can report test successes and failures it still has to actually run some tests to report on!

You can just have your app programmatically do stuff but to help you out with this we've also provided a new JWAutomate API.  If your app uses Java Swing you can use its very simple interface to interact with the UI in as simple and robust a way as possible.  

Each time you make a call to a JWAutomate method it will use the info provided to search for the UI control you want to use, then use it.  You can specify the entire frame as a search area or just a particular subcomponent.  

This means you don't need to manually identify the bits of the UI you want to hit, you just identify them in much the same way as a real user might.  Matching of button text and tooltips is partial and case insensitive to again make your tests easy and robust against errors or typos:

hitButton(Component parent, String text)
hitButtonTT(Component parent, String text)
hitJTable(Component parent)
nextJTable(Component parent)
getJTableSize(Component parent)
deselectJTable(Component parent)
scrollUpPage(Component parent)
scrollDownPage(Component parent) 
sleep(long millis)
sleepMins(double mins)
Component hitTab(Component parent, String text)
hitMenu(Component parent, String text)
hitList(Component parent)
int getListSize(Component parent)
nextList(Component parent)
hitList(Component parent, String text)


You can also search for components to then later use as a search-space for later automation:

JComponent findFirst(Component parent, String text, Class type)
JComponent findFirstTT(Component parent, String text, Class type) 
ArrayList<JComponent> findAll(Component parent, String text, Class type) 
ArrayList<JComponent> findAllTT(Component parent, String text, Class type) 


The combination of these APIs allow your test app to launch your normal app to run a typical user sequence with just a few lines of code, then report on its success or failure. 

Automating documentation screenshots

Another important but often neglected part of development is documentation.  In particular, as an app changes over time, screenshots can get old and be left out of date simply because the process of setting up the environment to take the screenshot and actually taking it is so expensive in terms of human resources.  If you need to enter a bunch of sample info into your app, then go through some interactions to get to the point where you can take the screenshot thats a very high cost for one screenshot.

The testing harness app and APIs above allow you to potentially automate the manual interactions here, but to make this even simpler we've included the ability for the test app to dump screenshots of any control, or even the entire app, and have them reported back to the test server. You can also use the same API to take screenshots of any errors during a test run:

public static void reportScreenshot(String name, Component comp, boolean standaloneSuccess)


Going one step further, we have an API method in JWAutomate which allows you to dump screenshots of virtually everything in your app from start to finish, leaving you with just a pile of carefully cut out screenshots you can use in your documentation:

dumpScreenshots(Component[] parent, File html, boolean visibleOnly, Class[] ignoreList)

Centralised control of distributed tests

The last step in the JWrapper testing APIs involved putting everything together along with JW IPC to allow what we think is the ultimate API for your testing app.

So far we've covered passing in properties to your normal app to tell it what to run as a test, but ideally it would be best if your test logic was all back in the test app in one place.  Further, if your app is a client-server app or maybe if you just want to test lots of copies of it at the same time, you really need some form of centralised control so you can have your client do X then your server do Y.

JWTestControl provides you with exactly this.   First off, your test app launches JWTestControl:

listenForShared(int port, int mcport)


Thereafter, your normal app, client, server, anything you like really, can implement JWTestable and share itself with your test control server:

shareJWT(JWTestable test, String host, int port)

public interface JWTestable {
    public String getTestableAppName();
    public void call(String str, Message m) throws IOException;
    public void testControlConnectionFailed();
}


Your JWTestable app has now deferred control back to your test app.  Rather than being told a test to run on its own, it can now present your test app with a set of capabilities and your test app can centrally instruct all your apps to do whatever it wants, they can act independently of each other or they can act in concert to simulate specific complex situations.  Your test control server will automatically pick up any JWTestable apps shared with it and allow your test app to instruct them however it likes, either by picking off a particular JWTestable instance and talking to it specifically or by treating them as a pool, asking any of them to perform a test task:

int getConnected(String name)
int getAvailable(String name)
getShared(String name, int index)
popShared(String name, int timeout)

callOne(String name, String str, Message m)
callOne(String name, String str) 
callN(int N, String name, String str, Message m)
callN(int N, String name, String str) 
callAll(String name, String str, Message m)
callAll(String name, String str) 


Any calls your test app now makes, it just needs to specify the name of the shared JWTestable type (e.g. "myClient" or "myServer") and it can then direct calls to 'do stuff' into either of them.

Your normal apps can now leave out the test logic and just have a 'driving API' that they provide to your central testing app.  Your test app has full control to launch any and all of your normal apps in a standard environment thanks to JWrapper's usual APIs, and control them individually or as a pool with the new test APIs.

]]>
<![CDATA[Preventing Corrupt Files in Java]]>Mon, 01 Sep 2014 15:40:14 GMThttps://www.jwrapper.com/blog/preventing-corrupt-files-in-javaOur new JWrapper release brings some important fixes and Yosemite signing support but also adds a new API.  This new API, though very simple, can save you a lot of time and headaches.

Few useful applications run without at some point having to save information and later load it.  This may just be user preferences which could easily be discarded and recreated without much of an impact on the user or it may be something much more important and crucial to its operation.

In either case you to provide the user with the best possible experience you want to ensure that this information is saved safely and completely so that the app can be confident of being able to load it when the user next needs it.

Sources Of File Corruption

The most obvious form of corruption when saving a file comes from a major disk failure.  In such a case the app can only do so much to retain the data and it will often be up to the user to have backed everything up.  In cases where apps are dealing with truly critical data they may incorporate a backup function or use a backend database but for a lot of apps this is a problem outside of their scope.

Much more common though are app and operating system failures, disk space issues or other recoverable problems where the app has failed to write the full contents of the file and may have been prevented from recovering from the failure (for example on an unexpected operating system shutdown or a lock-up).  Conscientious apps that continuously save files to save ongoing work dramatically increase their chances of hitting this case just by increasing the frequency of saves.  However, there are relatively simple ways to avoid this common problematic case of creating a 'broken' file which it will inevitably fail to read on the next run.

Avoiding Special Formats

Some sort of generalised protection from this case seems like a good idea and any method of avoiding these corruptions would ideally have a number of features:

  1. Be robust
  2. Keep things as simple to use as possible
  3. Don't slow down I/O significantly
  4. Avoid special file formats

The first three here are pretty simple but the last is less obvious.  If you are writing a file to disk and you want to be sure that it has written in its entirity, an initially attractive method might be to use markers within the file such that on loading, it would be easy to detect if the file was partially written or not.  This plus some saving of previous versions might be enough to do the job.

The issue is that this only works where the file format is custom.  If you are saving JPEGs and you want to ensure that the saved JPEG is always valid then you can't adapt the file format to suit your case.

Borrowing From Filesystem Design - Simple Journaling

Instead, what you need is a simple version of what most modern filesystems today do at a low level on disk - Journaling (note that although they do it on disk, this doesn't prevent your app from creating partially saved files.  If the disk is only asked to write 50% of your config file then it doesn't help that you can be sure it definitely saved that 50% correctly).

In journaling, the intent of the changes is first stored somewhere and such that once the changes are made, if they are only able to be partially made for any reason, they can be finished off when the file is next accessed.  This ensures that the file is kept in a consistent state when accessing it.

A new simple API in JWrapper - JWAtomicFileOutputStream - does exactly this.  It is used a simple alternative to FileOutputStream but rather than saving directly into the target file it first saves any data into a temporary file in the same folder as your target file.  Once you have finished writing data and call the close() method it will flush data into your new file, remove your existing file and rename the new version into its place.  This means that at any stage of this process you can always:

1) be sure there is a valid (fully written) copy of the file
2) know which is the valid and most up to date copy

When loading you need only call JWAtomicFileOutputStream.prepareForReading and JW will check if the file was partially saved.  If it is it will restore it back to a valid state so that you can load the file as usual.

This doesn't slow down your I/O or modify your file format in any way - you can use it to save JPEGs or any other type of file and it allows you to use it as a drop-in replacement for any existing FileOutputStreams you want to protect.  It also allows you to retain backwards compatibility with any other apps or versions that load your saved file, since it will be ultimately saved in exactly the same format.

A trivial change which allows you to avoid issues for your users and support queries for yourself.

]]>
<![CDATA[New JWrapper Release - OSX Yosemite Signing Support and More]]>Mon, 01 Sep 2014 14:58:56 GMThttps://www.jwrapper.com/blog/new-jwrapper-release-osx-yosemite-signing-support-and-moreWe have a new JWrapper release available to download as of today.  This new release adds OSX Yosemite signing support, a new atomic file saving API (will be covered in the next blog post), and a number of fixes.

Head to our download page to get the full details and the latest version.

OSX Yosemite Signed DMG Rejection

With the new version of OSX (Yosemite) coming in Autumn it will be bringing with it a change to OSX's signing.  

DMG files signed with the existing method can still be run but when opening OSX will produce a warning complaining that the DMG files are 'damaged' and will refuse to open them.  To open the DMG the user can still right click and select 'Open' but clearly avoiding this case is preferable.

Apple have enforced this new signature style quite abruptly which leads us to speculate that it may be countering security problems in the previous method.

The latest version of JWrapper supports Yosemite-style signing and DMGs built with it will open fine without any warnings.

Fixes and new File API

This new version also fixes a few customer reported issues.

In the first of these JWrapper might fail to set up an app properly due to some issues around running HTTP proxy detection and a direct download attempt.

In the second reported issue JWrapper might import a system JRE which is of too low a version to unpack the app, depending on the system JRE version and the app class version this may cause the install to fail.

Stay tuned for more info about a new file API to easily ensure valid config files at all times.
]]>
<![CDATA[Antivirus Software - The Shoddy Would-Be Gatekeepers Of The Internet]]>Fri, 01 Aug 2014 16:46:10 GMThttps://www.jwrapper.com/blog/antivirus-software-the-shoddy-would-be-gatekeepers-of-the-internetAnyone who has spent any time with computers will be familiar with Antivirus software.  Antivirus software on the surface seems innocuous, even laudable - after all its protecting people from viruses, trojans, and all sorts of malicious software that would take over their machines.

But anyone who has developed commercial software for even a short time will have bumped into quite a different side of Antivirus software.  A side that silently blocks apps from running, pops up erroneous and borderline libellous statements, randomly terminates both network connections and processes and randomly deletes files from a software installation.

When software is handling restrictions at the operating system level the restrictions are clear and (mostly) predictable.  You can try to open a file for writing and your request may be denied, maybe there isn't space on the disk or maybe your app doesn't have permissions.  You can try to open a socket to a remote machine and perhaps it will fail to connect.  You can anticipate these issues because they are built in restrictions, they are part of the API you are using and you can handle them gracefully.  Your app might not be able to continue doing what it intended to but it can report this to the user and/or change its behaviour appropriately.  The end user can get a meaningful message which will help them to understand what the underlying issue may be (maybe they have a firewall and your message will give them the hint they need to open it up) and in the worst case the developer can get a useful message and explain to the user how to rectify the issue.

Anticipating these restrictions and handling them well is part of good software development, but what do you do when things happen to your app that are entirely inexplicable?

Bringing stability to your computer, by adding unexpected and unanticipatable failure to any app

The bread and butter of an antivirus tool is to check apps that run against a database of viruses and looking for signatures - matches between how a virus is known to infect an app and the app that looks to be infected. 

The problem is, virus and trojan creators know that antivirus tools work this way.  Viruses and trojans are no longer simple bolt-ons that attach themselves to software, instead they will employ a wide variety of tricks to hide themselves and make themselves undetectable by Antivirus software.  Seeing the world as executable files that have been modified in an easily detectable way by viruses no longer works.

To counter this, antivirus software now often relies heavily on heuristics - algorithms and rule sets which look at other aspects of the software, such as what it does, what files it accesses, where it came from, where it runs from and anything else you can think of, to determine whether it is maybe malicious.

The problem is that this is using rules to analyse software behaviour in this way with zero high level understanding of what that software is for and what it should be doing is doomed to failure.  Heuristics therefore either are too lenient and fail to do anything except for the most bluntly malicious software or are much too strict and create false positives causing problems for perfectly valid, trustworthy software.  This leads to popup messages like "Warning! Malicious Software Detected!" when actually it is a failure of a rule set within the Antivirus software.

The steps antivirus software take to counter this malicious software are similarly fraught with problems.  Antivirus software can't always know when an app is being installed, what constitutes the various parts of an app installation or whether it is possibly malicious before it has been installed or even before it has run.

This often leads to the Antivirus software detecting just parts of apps and falsely tagging them as malicious, then deleting, terminating, blocking or otherwise interfering with in an unpredictable way, those parts of an app which it has falsely determined to be malicious.  This is again because the rule set and heuristics lack any higher level understanding of what constitutes the app or its expected function or behaviour.

In extreme cases they can even attack the very operating system they are running on.  In 2007 for example a Symantec Antivirus update caused it to interpret critical operating system files as viruses and delete them.  Similarly in 2010 McAfee VirusScan detected svchost.exe, a normal part of windows, as a virus on Windows XP causing the machine to lose all network access and enter into a continuous reboot cycle.

Even more incredibly in 2012 Sophos Antivirus identified itself as malicious software and deleted its own critical binaries. (Antivirus heuristics have probably never been more accurate).

These random interferences can cause real headaches for developers trying to understand why a customer is having an issue.  If the app launched then why did it suddenly fail?   If the install looks fine in other ways then why are those specific files missing?  Has the customer deleted them?  Disk corruption?  Did something go weirdly wrong in the installer?  

Coming to the correct conclusion that some other software has effectively attacked and broken your own software is never a logical path unless you are already well versed in the whims of Antivirus apps.

Antivirus software could do much more to make its actions cleaner and their implications clearer.  It could at least try to quarantine (delete) an entire app instead of one library file or executable.  It could pop up a message explaining exactly what it has done and how this might make app X, which may also be called Y, (since that is its directory in Program Files or /opt) to operate in an unexpected way, produce corrupt files or fail to run altogether.

But when an affected app fails to run, the customer reaches out to the provider of that app, not the Antivirus software.  Since the headaches are directed at the affected app vendor and not to the Antivirus software provider there is no real incentive to improve the software or even make it more clear what its breaking.  In fact there is a disincentive; right now the mess made is someone else's problem, the more clear the Antivirus software is that it is the cause of the problem the more likely the headache will come back to them. 

Protecting your network, by closing the gate after the horse has bolted

Antivirus software in recent years has been branching out and today will often include not just checking for malicious software but will also include some form of network security.  This varies from app to app but often it will include checking downloads for malicious software and other less clear restrictions on the behaviour that software is allowed to exhibit.

Again since we are in a turing-complete world there aren't simple rules to separate the good apps from the bad.  Antivirus software will again often fall back on heuristics that either do nothing or that identify reasonable behaviour as malicious and trigger various unexpected and unanticipatable reactions like terminating processes or network connections.

Again the mess is left for the developer and end user to work out.  Maybe the app is crashing?  Is this a failing router or switch?  Maybe a problem with the network card or its driver?  Or maybe its a problem with the app somewhere in its use of the network?

Hours and days of support can pass by trying to resolve problems and failures that, for those unaware of the potential actions of Antivirus software, can appear inexplicable and totally illogical.

Whats worse is that in many cases these actions are taken in the name of 'securing' your network and your computer, but in reality they do anything but.  If a malicious app creates a network connection to try to upload your credit card details to some criminal network then it would seem like an obvious idea to try to terminate that network connection.  

The problem is your credit card details are very small, and by the time you have analysed the data passing through, determined that it isn't what you expect and then terminated it the details could have passed through a thousand times over.  The average credit card number consists of just a 16 digit number and maybe an expiry date, maybe even an address.  At the most it might be 100 bytes of information but even an ancient dialup modem could transfer 7,000 bytes every second.  A fairly slow ADSL connection today might transfer 100,000 bytes per second, equivalent to 1000 credit card numbers every second, or a credit card number in 0.001 seconds.

If you are terminating the network connection even after just 5 or 10 seconds then this has no impact on security.  Further if you then allow the app to keep creating these connections that you terminate after 5 or 10 seconds (yes, we have seen this a number of times) then you actually don't restrict it at all, it can just pick up where it left off and keep uploading.

This type of behaviour is what security experts would refer to as 'security theatre'.

Increasing your security, by failing to prevent basic MITM attacks

Focusing on security marketing points rather than real security is bad enough, but to compound the issue a recent presentation by Joxean Koret at the SyScan 360 security conference earlier this month would suggest that Antivirus vendors are not only failing to provide real security, but opening up computers to attack with shoddy practices in their own software.

Koret identified many top Antivirus software providers that download unauthenticated updates over a plain HTTP connection, providing an attacker an easy route to perform a man-in-the-middle attack and replace the update with any malicious software they like.

Like flu or the common cold, until some magical and much desired cure comes along Antivirus software is just a fact of life and a cost of business.  Knowing what the issues could be in advance can save you a lot of going round in circles and following logical paths only to find out, after much wasted time, that the real cause of the issue is far more absurd than you would imagine.  

]]>