( ! ) Deprecated: Function WP_Dependencies-&gt;add_data() was called with an argument that is <strong>deprecated</strong> since version 6.9.0! IE conditional comments are ignored by all supported browsers. in /var/www/html/wp-includes/functions.php on line 6131
Call Stack
#TimeMemoryFunctionLocation
10.0001484224{main}( ).../index.php:0
20.0001484576require( '/var/www/html/wp-blog-header.php ).../index.php:17
30.11784389944require_once( '/var/www/html/wp-includes/template-loader.php ).../wp-blog-header.php:19
40.11924419264include( '/var/www/html/wp-content/themes/twentyfifteen/archive.php ).../template-loader.php:125
50.11924419264get_header( $name = ???, $args = ??? ).../archive.php:19
60.11924419480locate_template( $template_names = [0 => 'header.php'], $load = TRUE, $load_once = TRUE, $args = [] ).../general-template.php:48
70.11924419576load_template( $_template_file = '/var/www/html/wp-content/themes/twentyfifteen/header.php', $load_once = TRUE, $args = [] ).../template.php:749
80.11924420120require_once( '/var/www/html/wp-content/themes/twentyfifteen/header.php ).../template.php:814
90.11944427528wp_head( ).../header.php:18
100.11944427528do_action( $hook_name = 'wp_head' ).../general-template.php:3197
110.11944427744WP_Hook->do_action( $args = [0 => ''] ).../plugin.php:522
120.11944427744WP_Hook->apply_filters( $value = '', $args = [0 => ''] ).../class-wp-hook.php:365
130.11954549512wp_enqueue_scripts( '' ).../class-wp-hook.php:341
140.11954549512do_action( $hook_name = 'wp_enqueue_scripts' ).../script-loader.php:2311
150.11954549728WP_Hook->do_action( $args = [0 => ''] ).../plugin.php:522
160.11954549728WP_Hook->apply_filters( $value = '', $args = [0 => ''] ).../class-wp-hook.php:365
170.11974557248twentyfifteen_scripts( '' ).../class-wp-hook.php:341
180.11984558768wp_style_add_data( $handle = 'twentyfifteen-ie', $key = 'conditional', $value = 'lt IE 9' ).../functions.php:440
190.11984558768WP_Styles->add_data( $handle = 'twentyfifteen-ie', $key = 'conditional', $value = 'lt IE 9' ).../functions.wp-styles.php:245
200.11984558768WP_Dependencies->add_data( $handle = 'twentyfifteen-ie', $key = 'conditional', $value = 'lt IE 9' ).../class-wp-styles.php:385
210.11984558768_deprecated_argument( $function_name = 'WP_Dependencies->add_data()', $version = '6.9.0', $message = 'IE conditional comments are ignored by all supported browsers.' ).../class-wp-dependencies.php:317
220.11984559088wp_trigger_error( $function_name = '', $message = 'Function WP_Dependencies->add_data() was called with an argument that is <strong>deprecated</strong> since version 6.9.0! IE conditional comments are ignored by all supported browsers.', $error_level = 16384 ).../functions.php:5925
230.11994559840trigger_error( $message = 'Function WP_Dependencies-&gt;add_data() was called with an argument that is <strong>deprecated</strong> since version 6.9.0! IE conditional comments are ignored by all supported browsers.', $error_level = 16384 ).../functions.php:6131

( ! ) Deprecated: Function WP_Dependencies-&gt;add_data() was called with an argument that is <strong>deprecated</strong> since version 6.9.0! IE conditional comments are ignored by all supported browsers. in /var/www/html/wp-includes/functions.php on line 6131
Call Stack
#TimeMemoryFunctionLocation
10.0001484224{main}( ).../index.php:0
20.0001484576require( '/var/www/html/wp-blog-header.php ).../index.php:17
30.11784389944require_once( '/var/www/html/wp-includes/template-loader.php ).../wp-blog-header.php:19
40.11924419264include( '/var/www/html/wp-content/themes/twentyfifteen/archive.php ).../template-loader.php:125
50.11924419264get_header( $name = ???, $args = ??? ).../archive.php:19
60.11924419480locate_template( $template_names = [0 => 'header.php'], $load = TRUE, $load_once = TRUE, $args = [] ).../general-template.php:48
70.11924419576load_template( $_template_file = '/var/www/html/wp-content/themes/twentyfifteen/header.php', $load_once = TRUE, $args = [] ).../template.php:749
80.11924420120require_once( '/var/www/html/wp-content/themes/twentyfifteen/header.php ).../template.php:814
90.11944427528wp_head( ).../header.php:18
100.11944427528do_action( $hook_name = 'wp_head' ).../general-template.php:3197
110.11944427744WP_Hook->do_action( $args = [0 => ''] ).../plugin.php:522
120.11944427744WP_Hook->apply_filters( $value = '', $args = [0 => ''] ).../class-wp-hook.php:365
130.11954549512wp_enqueue_scripts( '' ).../class-wp-hook.php:341
140.11954549512do_action( $hook_name = 'wp_enqueue_scripts' ).../script-loader.php:2311
150.11954549728WP_Hook->do_action( $args = [0 => ''] ).../plugin.php:522
160.11954549728WP_Hook->apply_filters( $value = '', $args = [0 => ''] ).../class-wp-hook.php:365
170.11974557248twentyfifteen_scripts( '' ).../class-wp-hook.php:341
180.14854560944wp_style_add_data( $handle = 'twentyfifteen-ie7', $key = 'conditional', $value = 'lt IE 8' ).../functions.php:444
190.14854560944WP_Styles->add_data( $handle = 'twentyfifteen-ie7', $key = 'conditional', $value = 'lt IE 8' ).../functions.wp-styles.php:245
200.14854560944WP_Dependencies->add_data( $handle = 'twentyfifteen-ie7', $key = 'conditional', $value = 'lt IE 8' ).../class-wp-styles.php:385
210.14854560944_deprecated_argument( $function_name = 'WP_Dependencies->add_data()', $version = '6.9.0', $message = 'IE conditional comments are ignored by all supported browsers.' ).../class-wp-dependencies.php:317
220.14854561264wp_trigger_error( $function_name = '', $message = 'Function WP_Dependencies->add_data() was called with an argument that is <strong>deprecated</strong> since version 6.9.0! IE conditional comments are ignored by all supported browsers.', $error_level = 16384 ).../functions.php:5925
230.14864561488trigger_error( $message = 'Function WP_Dependencies-&gt;add_data() was called with an argument that is <strong>deprecated</strong> since version 6.9.0! IE conditional comments are ignored by all supported browsers.', $error_level = 16384 ).../functions.php:6131

J2ME Game Optimization Secrets (part 3)

Out of the loop?


Code inside a for() loop will be executed as many times as the loop iterates. To improve performance, therefore, we want to leave as much code as possible outside of our loops. We can see from the profiler that our paint() method is being called 101 times, and the loop inside iterates 16 times. What can we leave out of those two loops? Let’s start with all those declarations. We are declaring a Font, a String, an Image and a Graphics object every time paint() is called. We’ll move these outside of the method and to the top of our class.


public static final Font font =
  Font.getFont( Font.FACE_PROPORTIONAL,
                Font.STYLE_BOLD | Font.STYLE_ITALIC,
                Font.SIZE_SMALL);
public static final int graphicAnchor =
                   Graphics.VCENTER | Graphics.HCENTER;
public static final int textAnchor =
      Graphics.TOP | Graphics.LEFT;
private static final String MESSAGE = ” ms per frame”;
private String msMessage = “000” + MESSAGE;
private Image stringImage;
private Graphics imageGraphics;
private long oldFrameTime;


You’ll notice I made the Font object a public constant. This is often a useful thing to do in your apps, as you can gather the font declarations you use most together in one place. I have found the same goes for anchors, so I’ve done the same with the text and graphic anchors. Pre-calculating these things keeps those calculations, however insignificant, out of our loop.


I’ve also made the MESSAGE a constant. That’s because Java loves to create String objects all over the place. Strings can be a huge memory drain if they’re not controlled. Don’t take them for granted, or you will probably bleed memory, which can in turn affect performance, especially if the garbage collector is being called too often. Strings create garbage, and garbage is bad. Using a String constant reduces the problem. Later we’ll see how to use a StringBuffer to completely stop memory loss from String abuse.


Now that we’ve made these things instance variables, we need to add this code to the constructor:


stringImage = Image.createImage( font.stringWidth( msMessage ),
                                 font.getBaselinePosition() );
imageGraphics = stringImage.getGraphics();
imageGraphics.setFont( font );


Another cool thing about getting our Graphics object up-front is that we can set the font once and then forget about it instead of setting it every time we iterate through the loop. We still have to wipe the Image object each time using fillRect(). Gung-ho coders might see an opportunity there to create two Graphics objects from the same Image, and pre-set the color of one to COLOR_BG for the call to fillRect() and COLOR_FG on the other for the calls to drawString(). Unfortunately, the behavior of getGraphics() when called multiple times on the same Image is ill-defined in J2ME and differs across platforms so your optimization tweak might work on Motorola but not NOKIA. If in doubt, assume nothing.


There is another way to improve on our paint() method. Using our brain again we realize that we only need to re-draw the string if the frameTime value has changed since the method was last called. That’s where our new variable oldFrameTime comes in. Here’s the new method:


public void paint(Graphics g) {
  g.setColor( COLOR_BG );
  g.fillRect( 0, 0, getWidth(), getHeight() );
  if ( frameTime != oldFrameTime ) {
    msMessage = frameTime + MESSAGE;
    imageGraphics.setColor( COLOR_BG );
    imageGraphics.fillRect( 0, 0, stringImage.getWidth(),
                            stringImage.getHeight() );
    imageGraphics.setColor( COLOR_FG );
    imageGraphics.drawString( msMessage, 0, 0, textAnchor );
  }
  for ( int i  = 0 ; i < DRAW_COUNT ; i ++ ) {
    g.drawImage( stringImage, getRandom( getWidth() ),
                 getRandom( getHeight() ), graphicAnchor );
  }
  oldFrameTime = frameTime;
}


The Profiler now shows that the time spent in OCanvas paint is down to 42.01% of the total. Comparing the frameTime across calls to paint() resulted in drawString() and fillRect() being called 69 times instead of 101. That’s a decent savings, and there’s not much more to go, but now it’s time to get serious. The more you optimize, the harder it gets. Now we are down to scraping out the last pieces of superfluous, cycle-eating code. We’re dealing with shaving off very small percentages, or even fractions of percentages now, but if we’re lucky, they’ll add up to something significant.


Let’s start with something easy. Instead of calling getHeight() and getWidth(), let’s call those methods once and cache the results outside our loop. Next, we’re going to stop using Strings and do everything manually with a StringBuffer. We’re then going to shave a little off the calls to drawImage() by restricting the drawing area through calls to Graphics.setClip(). Finally, we’re going to avoid making calls to java.util.Random.nextInt() inside our loop.


Here are our new variables…


  private static final String MESSAGE = “ms per frame:”;
  private int iw, ih, dw, dh;
  private StringBuffer stringBuffer;
  private int messageLength;
  private int stringLength;
  private char[] stringChars;
  private static final int RANDOMCOUNT = 256;
  private int[] randomNumbersX = new int[RANDOMCOUNT];
  private int[] randomNumbersY = new int[RANDOMCOUNT];
  private int ri;


…and here is the new code for our constructor:


iw = stringImage.getWidth();
ih = stringImage.getHeight();
dw = getWidth();
dh = getHeight();
for ( int i = 0 ; i < RANDOMCOUNT ; i++ ) {
  randomNumbersX[i] = getRandom( dw );
  randomNumbersY[i] = getRandom( dh );
}
ri = 0;
stringBuffer = new StringBuffer( MESSAGE+”000″ );
messageLength = MESSAGE.length();
stringLength = stringBuffer.length();
stringChars = new char[stringLength];
stringBuffer.getChars( 0, stringLength, stringChars, 0 );


You can see we’re pre-calculating Display and Image dimensions. We’re also cacheing the results of 512 calls to getRandom(), and we’ve dispensed with the msMessage String in favor of a StringBuffer. The meat is still in the paint() method, of course:


  public void paint(Graphics g) {
    g.setColor( COLOR_BG );
    g.fillRect( 0, 0, dw, dh );
    if ( frameTime != oldFrameTime ) {
      stringBuffer.delete( messageLength, stringLength );
      stringBuffer.append( (int)frameTime );
      stringLength = stringBuffer.length();
      stringBuffer.getChars( messageLength,
                             stringLength,
                             stringChars,
                             messageLength );
      iw = font.charsWidth( stringChars, 0, stringLength );
      imageGraphics.setColor( COLOR_BG );
      imageGraphics.fillRect( 0, 0, iw, ih );
      imageGraphics.setColor( COLOR_FG );
      imageGraphics.drawChars( stringChars, 0,
                               stringLength, 0, 0, textAnchor );
    }
    for ( int i  = 0 ; i < DRAW_COUNT ; i ++ ) {
      g.setClip( randomNumbersX[ri], randomNumbersY[ri], iw, ih );
      g.drawImage( stringImage, randomNumbersX[ri],
                   randomNumbersY[ri], textAnchor );
      ri = (ri+1) % RANDOMCOUNT;
    }
    oldFrameTime = frameTime;
  }


We’re using a StringBuffer now to draw the characters of our message. It’s easier to append characters to the end of a StringBuffer than to insert them at the beginning, so I’ve switched our display text around and the frameTime is now at the end of the message, e.g. “ms per frame:120”. We’re just writing over the last few frameTime characters each time, and leaving the message part intact. Using a StringBuffer explicitly like this saves the system from creating and destroying Strings and StringBuffers each time through our paint() method. It’s extra work, but it’s worth it. Note that I’m casting frameTime to an int. I found that using append(long) caused a memory leak. I don’t know why, but it’s a good example of why you should use the utilities to keep an eye on things.


We’re also using font.charsWidth() to calculate the width of the message image so that we have to do the minimum of drawing. We’ve been using a proportional font, so the image for “ms per frame:1” will be smaller than the image for “ms per frame:888”, and we’re using Graphics.setClip() so we don’t have to draw the extra. This also means we only have to fill a rectangle big enough to blank out the area we need. We’re hoping that the drawing time we save makes up for the extra time spent calling font.charsWidth().


It may not make much of a difference here, but this is a great technique to use in a game for drawing a player’s score on the screen. In that case, there’s a big difference between drawing a score of 0 and a score of 150,000,000. This is hampered somewhat by the implementation’s incorrect return values for font.getBaselinePosition(), which seems to return the same value as font.getHeight(). Sigh.


Finally, we’re just looking up the pre-calculated “random” co-ordinates in our two arrays, which saves us making those calls. Note the use of the modulo operator to implement a circular array. Note also that we’re using the textAnchor for drawing both the image and the string now so that setClip() works correctly.


We are now firmly in a gray area with respect to the numbers this version of the code produces. The profiler tells me that the code is spending roughly 7% more time in paint() than without these changes. The call to font.charsWidth() is probably to blame, weighing in at 4.6%. ( That’s not great, but it could be reduced. Notice that we’re retrieving the width of the MESSAGE string every time. We could easily calculate that ahead of the loop body and simply add it to the frameTime width. ) Also, the new call to setClip() is labelled 0.85%, and seems to significantly increase the percentage of time spent in drawImage ( to 33.94% from 27.58% ).


At this point, it looks like all this extra code must certainly be slowing things down, but the values generated by the application contradict with this assumption. Figures on the emulator fluctuate so much as to be inconclusive without running longer tests but my i85s reports that things are a little faster with the extra clipping code than without, coming in at 37130ms without either call to setClip() or charsWidth(), and coming in at 36540 with both. I ran this test as many times as I had patience for, and the results were solid. This highlights the issues of varying execution environments. Once you get to the point where you’re not sure if you’re making headway, you might be forced to continue all your testing on the hardware, which would require a lot of installing and uninstalling of JAR files.


So it looks like we’ve squeezed a lot more performance from our graphical routines. Now it’s time to take the same high-level and low-level approaches with our work() method. Let’s review that method:


  public synchronized int work( int[] n ) {
    r = 0;
    for ( int j = 0 ; j < DIVISOR_COUNT ; j++ ) {
      for ( int i = 0 ; i < n.length ; i++ ) {
        divisor = getDivisor(j);
        r += workMore( n, i, divisor );
      }
    }
    return r;
  }


Every time through the loop in run() we’re passing in our array of numbers. The outer loop in the work() method calculates our divisor, then calls workMore() to actually perform the division. All kinds of things are wrong here, as you can probably tell. For a start, the programmer has put the call to getDivisor() inside the inner loop. Given that the value of j does not change through the inner loop, the divisor is an invariant, and really belongs outside the inner loop.


But let’s think about this some more. The call itself is completely unnecessary. This code does the same thing…


  public synchronized int work( int[] n ) {
    r = 0;
    divisor = 1;
    for ( int j = 0 ; j < DIVISOR_COUNT ; j++ ) {
      for ( int i = 0 ; i < n.length ; i++ ) {
        r += workMore( n, i, divisor );
      }
      divisor *= 2;
    }
    return r;
  }


…without that call to getDivisor(). Now our profiler is telling me that we are spending 23.72% in our run() method, versus 38.78% before we made these improvements. Always optimize with your head first before messing with low-level optimization tricks. With that said, let’s take a look at some of those tricks.


J2ME Game Optimization Secrets (part 4)

Low-Level Optimization


All programmers are familiar with the concepts of the sub-routine and the function – separate out common code to avoid duplicating it in several places around your app. Unfortunately, this commonly “Good” programming practice can impact performance because method calls involve a certain amount of overhead. The easiest way to reduce the amount of time it takes to call a method is by carefully selecting its declaration modifiers. Our programmer has been very cautious, and has made his work() and workMore() methods synchronized, in case some other thread might call them simultaneously. This is all well and good, but if we’re serious about performance, we often have to make sacrifices, and today we will be sacrificing safety.


Well, not really. We know for a fact that no-one else is going to be calling these methods, so we can de-synchronize them without too much worry. What else can we do? Take a look at this list of method types:


synchronized methods are the slowest, since an object lock has to be obtained
interface methods are the next slowest
instance methods are in the middle
final methods are faster
static methods are fastest
So we definitely shouldn’t be making anything synchronized, and it looks like we can even mark work() and workMore() as final static methods. Doing this cut 1% from the time the emulator spent inside run().


Another factor that affects the performance of method calls is the number of parameters passed into the method. We are calling workMore() 51712 times, passing an int array and two ints into the method and returning an int each time. In this, somewhat trivial, example it’s going to be easy to collapse the workMore() method into the the body of work() to avoid the call entirely. In the real world, that decision might be harder to make, especially if it means that code will be duplicated around your application. Test with the profiler and on the device to see how much difference it actually makes before taking that step. If you can’t remove the method altogether, try to reduce the number of parameters you’re passing into it. The more parameters, the greater the overhead.


  public final static int work( int[] n ) {
    divisor = 1;
    r = 0;
    for ( int j = 0 ; j < DIVISOR_COUNT ; j++ ) {
      for ( int i = 0 ; i < n.length ; i++ ) {
        r += n[i] * n[i] / divisor + n[i];
      }
      divisor *= 2;
    }
    return r;
  }


Wow! Removing the call to workMore() slashed the amount of time spent in run to 9.96%. From here on it will be uphill all the way. Let’s look at two general optimization techniques – strength reduction and loop unrolling.


Strength reduction is where you replace a relatively slow operation with a fast one that does exactly the same thing. The most common example is using the bitshift operators, which are equivalent to multiplication and division by a power of two. For example, x >> 2 is equivalent to x / 4 ( 2 to the power of 2 ) and x << 10 is equivalent to x * 1024 ( 2 to the power of 10 ). By an amazing coincidence, our divisor is always a power of 2 (isn’t that lucky!) so we can use bitshifting in place of division.


Unrolling loops reduces the overhead of flow control code by performing more than one operation each time through the loop, executing fewer iterations, or even removing the loop entirely. As our DIVISOR_COUNT is only 8, it’s going to be easy to unroll our outer loop:


public final static int work( int[] n ) {
  r = 0;
  for ( int i = 0 ; i < n.length ; i++ ) { r +=  n[i] * n[i]  + n[i]; }
  for ( int i = 0 ; i < n.length ; i++ ) { r +=  (n[i] * n[i] >> 1) + n[i]; }
  for ( int i = 0 ; i < n.length ; i++ ) { r +=  (n[i] * n[i] >> 2) + n[i]; }
  for ( int i = 0 ; i < n.length ; i++ ) { r +=  (n[i] * n[i] >> 3) + n[i]; }
  for ( int i = 0 ; i < n.length ; i++ ) { r +=  (n[i] * n[i] >> 4) + n[i]; }
  for ( int i = 0 ; i < n.length ; i++ ) { r +=  (n[i] * n[i] >> 5) + n[i]; }
  for ( int i = 0 ; i < n.length ; i++ ) { r +=  (n[i] * n[i] >> 6) + n[i]; }
  for ( int i = 0 ; i < n.length ; i++ ) { r +=  (n[i] * n[i] >> 7) + n[i]; }
  return r;
}


Two important points. First, you’ll notice that unrolling our loop requires us to duplicate some code. This is the last thing you want in J2ME, where developers are often fighting JAR bloat, but remember that the JARing process involves compression, and compression works best on repetitive data, so the above code might not make as big an impact on your jar size as you might think. Again, it’s all about the trade-off. Your code can be small, fast, easy to read. Pick any two. The second point is that the bitshift operators have a different precedence from / and *, so you will often have to put parentheses around statements that otherwise would not need them.


Unrolling the loop and using the bitshift operators shaved off slightly more than 1%. Not bad. Now let’s turn our attention to array access. Arrays are fast data structures in C, but for that reason they can also be dangerous – if your code starts accessing array elements beyond the end of the array, you’re over-writing sections of memory you shouldn’t be messing with and the consequences will most likely be dire.


In contrast, Java is a very safe language – running off the end of an array like that will simply throw an ArrayIndexOutOfBoundsException. The system checks for an invalid index value every time you access an array, which makes array access slower than in C. Again, there’s nothing we can do about the internals of array handling in Java, but we can work around it by making smart decisions. In the code above, for example, we’re accessing n[i] 24 times. We can omit a lot of those array accesses by storing the value of n[i] in a variable. A little high-level thought also reveals that we can rearrange things in a much smarter way like this…


  private static int divisor;
  private static int r;
  private static int ni;
  public final static int work( int[] n ) {
    r = 0;
    for ( int i = 0 ; i < n.length ; i++ )  {
      ni = n[i];
      r +=  ni * ni + ni;
      r +=  (ni * ni >> 1) + ni;
      r +=  (ni * ni >> 2) + ni;
      r +=  (ni * ni >> 3) + ni;
      r +=  (ni * ni >> 4) + ni;
      r +=  (ni * ni >> 5) + ni;
      r +=  (ni * ni >> 6) + ni;
      r +=  (ni * ni >> 7) + ni;
    }
    return r;
  }


We’ve eliminated a whole lot of looping and array accessing. Let’s now eliminate a whole lot of squaring using a technique known as common sub-expression elimination. We’re calculating the square of n[i] eight times each time through our loop. We can eliminate those repetitive calculations by working out the square once at the beginning:


  private static int r;
  private static int ni;
  private static int nis;
  public final static int work( int[] n ) {
    r = 0;
    for ( int i = 0 ; i < n.length ; i++ )  {
      ni = n[i];
      nis = ni * ni;
      r +=  nis  + ni;
      r +=  (nis >> 1) + ni;
      r +=  (nis >> 2) + ni;
      r +=  (nis >> 3) + ni;
      r +=  (nis >> 4) + ni;
      r +=  (nis >> 5) + ni;
      r +=  (nis >> 6) + ni;
      r +=  (nis >> 7) + ni;
    }
    return r;
  }


…which cuts down the time spent in run() to 6.18%. Not bad at all. Before we move on, let me say a couple more things about arrays. A little high-level optimization ( i.e. “thought” ) might reveal that an array isn’t necessarily the right data structure to use. Think about using a linked list or some other structure if that would increase performance. Secondly, if you are going to use an array and you ever need to copy its contents into another array, always use System.arraycopy(). It’s way faster than trying to write your own routine to do the same thing. Finally, arrays are generally higher performance than the java.util.Vector object. If you require the kind of functionality that a Vector offers, think about writing it yourself and run tests to make sure your code is faster.


Okay, we’re really running out of things to optimize. We just introduced another couple of variables to cache the array element and the value of that element squared. You may have been wondering why those variables have been declared outside the body of the method declaration. They’re outside because even declaring ints takes a little time and we should keep that out of our loop, right? Wrong!


Assume nothing. It’s true that we’re saving time by avoiding the int declarations, but this code may actually be slower than if those variables were declared locally, inside the method. That’s because local variables perform better, as the JVM takes longer to resolve variables declared outside a method. So let’s turn them into local variables.


Finally, we can tweak our for() loop slightly. Computers are generally better at comparing a number to zero than to any other non-zero number. That means we can turn our loop upside down and rewrite the method like this so we’re comparing against zero:


  public final static int work( int[] n ) {
    int r = 0;
    int ni;
    int nis;
    int i;
    for ( i = n.length ; –i >= 0 ; ) {
      ni = n[i];
      nis = ni * ni;
      r +=  nis  + ni;
      r +=  (nis >> 1) + ni;
      r +=  (nis >> 2) + ni;
      r +=  (nis >> 3) + ni;
      r +=  (nis >> 4) + ni;
      r +=  (nis >> 5) + ni;
      r +=  (nis >> 6) + ni;
      r +=  (nis >> 7) + ni;
    }
    return r;
  }


And that’s it! This code may be a little faster, but the profiler results are less conclusive. What is clear is that this method is tougher to read. There may be further room for improvement, but let’s instead take another look at our paint() method, to see if any of what we learned can be introduced there.


Remember what we learned about local variables? If you are forced to use an instance variable and you are referencing that variable multiple times inside a method, it might be worth introducing a local variable so that the JVM only has to resolve the reference once. You’ll introduce a declaration and an assignment which will slow things down, but as a rule of thumb, we’ll use that technique if an instance variable is referenced more than twice.


We can also use strength reduction in our paint() method to replace the modulo operator with a circular counter that uses a bit operator. This is only possible because the length of our random numbers cache array is (amazingly!) a power of two. Finally, we can juggle our comparisons to always compare with zero. Here’s our new and improved paint() method:


  public void paint(Graphics g) {
    StringBuffer sb = stringBuffer;
    Graphics ig = imageGraphics;
    char[] sc = stringChars;
    int sl;
    int ml = messageLength;
    int ril = ri;
    int iw = 0;
    g.setColor( COLOR_BG );
    g.fillRect( 0, 0, dw, dh );
    if ( frameTime – oldFrameTime != 0  ) {
      sb.delete( ml, stringLength );
      sb.append( (int)frameTime );
      sl = stringLength = sb.length();
      sb.getChars( ml, sl, sc, ml );
      iw = font.charsWidth( sc, 0, sl );
      ig.setColor( COLOR_BG );
      ig.fillRect( 0, 0, iw, ih );
      ig.setColor( COLOR_FG );
      ig.drawChars( sc, 0, sl, 0, 0, textAnchor );
    }
    for ( int i  = DRAW_COUNT ; –i >=0  ; ) {
      g.setClip( randomNumbersX[ril], randomNumbersY[ril], iw, ih );
      g.drawImage( stringImage, randomNumbersX[ril],
                   randomNumbersY[ril], textAnchor );
      ril++;
      ril &= 255;
    }
    ri = ril;
    oldFrameTime = frameTime;
  }


Again, we are at the end of the road with respect to profiler results. These changes don’t affect the number of times the graphics routines are called, so the difference will be minor at best. But when we combine all the changes we made to our work() method and load the new JAR onto the device, the difference is huge. My motorola i85s now completes the test in 14030ms – over twice as fast!


There is one last change to make to the code. I have left it to the end because it uses a method that is not particularly well documented and my experience has been that its behavior varies across implementations. Looking at the start() and run() methods on OCanvas, you can see that I’ve been using a separate animation thread. This is the traditional way of doing animation in Java. An issue with using this technique for games is that we are forced to pause every time we iterate through the loop to allow system events, such as key presses and command actions to be delivered. We call the wait() method in a synchronized block to make this happen. This is hardly optimized code. After all our hard work optimizing everything else, we’re actually stopping to do nothing right in the thick of things. What’s worse, it’s not easy to arrive at a good figure for WAIT_TIME. If we wait() too long, the game slows down. If we don’t wait() for long enough, key presses are missed and the game stops being responsive to user input.


J2ME provides a solution to this problem by using the Display.callSerially() method. The API states that callSerially( Runnable r ) “causes the Runnable object r to have its run() method called later, serialized with the event stream, soon after completion of the repaint cycle”. By using callSerially() we can miss out the call to wait() entirely. The system will ensure that our work() and paint() methods are called in synch with the user input routines, so our game will remain responsive. Here are the new methods…


  public void start() {
    started = frameStarted = System.currentTimeMillis();
    loopCounter = result = 0;
    finished = false;
    exitStatus = EXIT_DONE;
    run();
  }
  public void run() {
    frameTime = System.currentTimeMillis() – frameStarted;
    frameStarted = System.currentTimeMillis();
    if ( midlet.running && !finished ) {
      result += work( numbers );
      repaint();
      display.callSerially(this);
      loopCounter++;
      finished = ( loopCounter > LOOP_COUNT );
    }
    else {
      elapsed = System.currentTimeMillis() – started;
      midlet.exitCanvas( exitStatus );
    }
  }


…plus we have to declare and get a handle on the Display:


    Display display = Display.getDisplay( midlet );


Without the call to wait() my i85s now runs this code in 10180ms – around a 40% savings. You might expect a greater increase in performance, given that we just eliminated 100 calls that wait() 50ms, but remember this technique is also about responsiveness to user input.


Again, let me stress that this method of animation should be used with caution. I had trouble getting it to work on NOKIA, and all of their example code (even game code) uses the wait() technique instead. Even on Motorola I had problems using callSerially() if I added Command objects to the animated Canvas. Test carefully before you try this at home.


 

J2ME Game Optimization Secrets (part 5)

Other Techniques


One technique I was unable to include in my example code was the optimal use of a switch() statement. Switches are very commonly used to implement Finite State Machines, which are used in game Artificial Intelligence code to control the behavior of non-player actors. When you use a switch, it is good programming practice to write code like this:


  public static final int STATE_RUNNING = 1000;
  public static final int STATE_JUMPING = 2000;
  public static final int STATE_SHOOTING = 3000;
  switch ( n ) {
    case STATE_RUNNING:
      doRun();
    case STATE_JUMPING:
      doJump();
    case STATE_SHOOTING:
      doShoot();
  }


There’s nothing wrong with this, and the int constants are nice and far apart, in case we might want to stick another constant in between RUNNING and JUMPING, like STATE_DUCKING = 2500. But apparently switch statements can be compiled into one of two byte codes, and the faster of the two is used if the ints used are close together, so this would be better:


  public static final int STATE_RUNNING = 1;
  public static final int STATE_JUMPING = 2;
  public static final int STATE_SHOOTING = 3;


There are also some optimizations you can perform when using a Fixed Point math library. First, if you’re doing a lot of division by a single number, you should instead work out the inverse of that number and perform a multiplication. Multiplication is slightly quicker than division. So instead of…


  int fpP = FP.Div( fpX, fpD );
  int fpQ = FP.Div( fpY, fpD );
  int fpR = FP.Div( fpZ, fpD );


…you should rewrite it like this:


  int fpID = FP.Div( 1, fpD );
  int fpP = FP.Mul( fpX, fpID );
  int fpQ = FP.Mul( fpY, fpID );
  int fpR = FP.Mul( fpZ, fpID );


If you’re performing hundreds of divisions every frame, this will help. Secondly, don’t take your FP math library for granted. If you have source for it, open it up and take a look at what’s going on in there. Make sure all the methods are declared final static and look for other opportunities to improve the code. For example, you may find that the multiplication method has to cast both ints to longs and then back to an int:


public static final int Mul (int x, int y) {
  long z = (long) x * (long) y;
  return ((int) (z >> 16));
}


Those casts take time. Collision detection using bounding circles or spheres involves adding the squares of ints together. That can generate some big numbers that might overflow the upper bound of your int Fixed Point data type. To avoid this, you could write your own square function that returns a long:


    public static final long Sqr (int x) {
      long z = (long) x;
      z *= z;
      return (z >> 16);
    }


This optimized method avoids a couple of casts. If you’re doing a great deal of Fixed Point math, you might consider replacing all of the library calls in the main game loop with the long-hand math. That will save a lot of method calls and parameter passing. You may also find that when the math is written out manually you can reduce the number of casts that are required. This is especially true if you are nesting several calls to your library, e.g.


  int fpA = FP.Mul( FP.toInt(5),
                    FP.Mul( FP.Div( 1 / fpB ),
                    FP.Mul( FP.Div( fpC, fpD ),
                    FP.toInt( 13 ) ) ) );


Take the time to unravel nested calls like this and see if you can reduce the amount of casting. Another way to avoid casting to longs is if you know that the numbers involved are small enough that they definitely won’t cause an overflow.


To help with high-level optimization, you should look for articles on game programming. A lot of the problems presented by game programming such as fast 3D geometry and collision detection have already been solved very elegantly and efficiently. If you can’t find Java source, you will almost certainly find C source or pseudo-code to convert. Bounds checking, for example, is a common technique that we could have used inside our paint() method. Instead of clearing the entire screen every time, we really only need to clear the section of the screen that changes from frame to frame. Because graphics routines are relatively slow you will find that the extra housekeeping required to keep track of which parts of the screen need to be cleared is well worth the effort.


Some phone manufacturers offer proprietary APIs that help programmers get around some of the limitations J2ME presents, such as lack of sound, lack of Image transparency, etc. Motorola, for example, offers a floating point math library that uses floating point math instructions on the chip. This library is much faster than the fastest Fixed Point math library, and a lot more accurate. Using these libraries completely destroys the portability of your code, of course, but they may be an option to consider if deployment on many different handsets is not a concern.


Conclusions
Only optimize code if you need to
Only optimize where it counts
Use the profiler to see where to optimize
The profiler won’t help you on the device, so use the System timer on the hardware
Always study your code and try to improve the algorithms before using low-level techniques
Drawing is slow, so use the Graphics calls as sparingly as possible
Use setClip() where possible to minimize the drawing area
Keep as much stuff as possible out of loops
Pre-calculate and cache like crazy
Strings create garbage and garbage is bad so use StringBuffers instead
Assume nothing
Use static final methods where possible and avoid the synchronized modifier
Pass as few parameters as possible into frequently-called methods
Where possible, remove method calls altogether
Unroll loops
Use bit shift operators instead of division or multiplication by a power of two
You can use bit operators to implement circular loops instead of modulo
Try to compare to zero instead of any other number
Array access is slower than C, so cache array elements
Eliminate common sub-expressions
Local variables are faster than instance variables
Don’t wait() if you can callSerially()
Use small, close constants in switch() statements
Look inside your Fixed Point math library and optimize it
Unravel nested FP calls to reduce casting
Division is slower than multiplication, so multiply by the inverse instead of dividing
Use tried and tested algorithms
Use proprietary high-performance APIs with care to preserve portability
Where to next?
Optimization is a black art. At the heart of any computer lies the CPU and at the heart of Java lies a virtual CPU, the JVM. To squeeze the last ounce of performance from the JVM, you need to know a lot about how it functions beneath the hood. Specifically, you need to know what things the JVM can do fast, and what it does slowly. Look for sites with solid information on the inner workings of Java. You don’t necessarily have to learn how to program in byte code, but the more you know, the easier it will be to come up with new ways to optimize your applications for performance.


There’s no substitute for experience. In time you will discover your own secrets about the performance characteristics of J2ME and of the handsets you are developing for. Even if you can’t code around certain idiosynchrasies, you could design your next game around them. While developing my game I found that calling drawImage() five times to draw five images of 25 pixels each is much slower than calling it once to draw an image five times the size. That knowledge will definitely help shape my next game.


Good luck, and have fun.


Resources:



  1. J2ME’s official web site contains the latest on what’s happening on this front.

  2. Like wireless games? Read the Wireless Gaming Review.

  3. Discuss J2ME Game Development at j2me.org

  4. A great site on many aspects of Java Optimization

  5. Another great site on Optimization

  6. Many articles on J2ME performance tuning

  7. The amazing Graphics Programming Black Book by Michael Abrash
  8. The Art of Computer Game Design by Chris Crawford

Real World Experiences with the WMA and the Push Registry

Real World Experiences with the WMA and the Push Registry


Introduction


This article will recount my experiences on a recent project that involved use of the Wireless Messaging API (WMA) and the Push Registry. The Push Registry is a feature new to the MIDP 2.0 spec, and the WMA, while not a MIDP 2.0 feature, is an optional feature that can be found on several MIDP 1.0 and 2.0 phones.


The functionality achievable with the Push Registry is summarized as follows: the device first receives a message, and if the message contains a header that defines a specific port, the device will pass the message to the application that has been registered for that port. For Java applications, though, the message first gets passed to the JAM (Java Application Manager), and it in turn will pass the message to the J2ME application that has registered the port number.


The WMA allows an application to send and receive SMS or CBS messages while the application is running. When the application is not running (which is probably most of the time), it cannot receive messages unless it is registered with the Push Registry. Controlled by the JAM, the Push Registry will launch the application which has previously registered the port to which the incoming message is destined. The Push Registry can also be set to launch an application at predefined time, but that function will not be discussed here (as it does not apply to using the WMA).



Handling incoming messages


The WMA JavaDocs (specifically, the javax.wireless.messaging.MessageListener page) has an excellent reference implementation for receiving messages. Essentially, the application’s main thread implements the MessageListener interface and performs the main application logic.When a message arrives, a separate object (possibly within another thread) is passed the message and handles it. This is the model I implemented in my several of my client’s projects (with some subtle transformations, of course), and it works well (see Code Sample 1).


This implementation applies to messages received not only while the application is running, but also when the application is started due to a Push Registry notification. When the application is launched in this later way, the Push Registry is queried to see if messages are waiting for this application and processes any that are there.


One issue you may want (or have) to consider at the client application level is how to deal with multiple messages arriving at the same time. To handle all of the messages, they will need to be handled serially, or else some of the messages will be dropped. The downside of this is that if for each message the implementation might display some type of alert message or invoke a function of the application. So sending multiple messages to a destination at once is not a good idea. As always, and especially with this type of messaging we must be vigilant about making the user experience as friendly and simple as possible.


 


Security considerations with messages


An issue to consider with incoming messages is the authenticity of the sender. Assuming the sender had the proper privileges to send an SMS message on the carrier’s network, and further assuming the sender knew the port number at which the Java application is registered in the JAM (via the Push Registry or a live J2ME application that has requested a port), you still may want to include some application-specific way of authenticating the message.


The MIDlet-Push- parameter in the JAD has three comma-delimited values, the last of which is . Defining this value, which is basically a URL, allows incoming messages to be received only from the stated address. While this may be good for friendly network communications, this cannot be relied upon to be completely secure. Thus, you may want to define your own mechanism for validating the incoming message. The message may have cleared the device and the JAM’s security restrictions, but that does not mean the message is safe or valid.


One technique is to embed a binary hash at the head of every message sent by your server. This hash will then be checked for validity by your application every time a new message is received. In this scenario, the message is still read by the application, but it can be verified before starting to perform application logic.


In the current mobile space, security concerns of this ilk might not be so vital, but it may be crucial for enterprise-type applications.


 


Provisioning the Application


There are some additional deployment issues to take into account when using WMA or Push Registry. Applications using the Push Registry must be provisioned OTA (Over The Air), as installing via USB/infrared is not guaranteed to work (or, at the least, will not be one hundred percent functional). Assuming your OTA server is properly configured (correct MIME types, host address, and so on), the first issue to work through is the Push Registry URL that must be declared in the JAD property MIDlet-Push-. The URL will look like “sms://:16885”. The most difficult and unpredictable part of this URL is the all Java applications on the device that use the Push Registry must have a unique port number. If an application is already registered on port 16885, and the user downloads a new application that also tries to use port 16885, the installation of the new application will fail. As there is no way to know beforehand what ports are in use by other Java application, its kind of a gamble as to which ports are unused. At this time (mid-2004), not many applications use the Push Registry functionality, so port number conflicts should not be too much of a concern. In my projects, however, I did have to handle it.


The most flexible mechanism to handle this situation is to dynamically generate a port number for the application when the user chooses to download and install your application; in other words, a dynamically-created JAD file will be sent to the device (Note: this is not possible on some operators, particularly if the operator provisions the J2ME application themselves). As you will be tracking the user’s profile data anyway (in order to send SMS messages to the device in the first place), retaining a dynamically generated port number (versus a “one app-one port number” paradigm) is almost no extra work.


To create a dynamically generated port number, we chose to generate a random value between the port numbers 16000 and 16999 (*1). Beware that some OEMs/operators predefine some of these port numbers on their devices, so you may consider maintaining a list of “port numbers to avoid” which is incorporated into your random port number generator’s algorithm.


Now for the tough question: what happens when the user’s device already has an application installed which uses the SMS port number you have defined in your JAD? When this occurs, the JAM is required to halt the installation process and consider the process as failed.


There is a JAD attribute that can be set, MIDlet-Install-Notify, whose value is a URL to which the device can send a message to indicate the success or failure of the installation. According to the OTA provisioning spec (*2) (which is now part of the MIDP 2.0 spec, JSR-118 (*3)), the device will send a status report regarding the result of the install, to which the server can only reply with a HTTP 200. (The server can send more data, but, according the specs, the device must ignore it.) The possible response messages from the device are as follows (see the MIDP 2.0 spec for full details):


 


Status Code Status Message
900 Success
901 Insufficient Memory
902 User Canceled
903 Loss of Service
904 JAR size mismatch
905 Attribute mismatch
906 Invalid Descriptor
907 Invalid JAR
908 Incompatible Configuration or Profile
909 Application authentication failure
910 Application authorization failure
911 Push registration failure
912 Deletion notification
 


You can setup a server-side component to listen for incoming messages about install status reports. In addition to recording additional information about the deployment of your application, you can track and react to installation failures based on the status code returned. One possibility for recovering from a failed installation is to send a WAP Push message to the device with a URL for downloading the JAD and application again. If the user is reinstalling the application due to a port number conflict, the previous port number should be excluded from new port numbers that are generated. Admittedly, this WAP Push technique was not implemented in our projects due to the complex (and potentially confusing) nature of the user interaction.


 


Getting messages to the device


For various reasons, not just anybody is allowed to send SMS messages to devices. Thus, a mobile development company ends up with two options: forge a relationship with each individual carrier or partner with an SMS aggregator. As the former option is far from being a trivial task (the business needs alone are daunting), working with an SMS aggregator is a viable option as they have already created partnerships with many carriers and usually have a simple API that you can use (rather than writing your own SMPP code).


Two leading aggregators in the U.S. are MBlocks and SimpleWire. As my company had contacts there, we opted to use SimpleWire’s services. Typically, you have an account with the aggregator and pass your account information with every SMS message that you send. SimpleWire’s API is simple and does not take much time to integrate into your server-side components (my current implementation consists of about fifteen lines of simple code – see Code Sample 2).


One quasi-problem I ran into is that after my servlet transmitted a message there often was a delay before the device received it (3 to 10 seconds). For the vast majority of uses, though, the delay will be irrelevant, although it is something to be aware of.


Another issue to keep in mind is that messages are limited in the size of data they can hold. While this does vary from carrier to carrier, the maximum data size for some carriers is 160 characters (single-byte characters, that is) per message. While you may have more data space with some carriers, it is probably best to keep message length (either text or binary) to an absolute minimum. To make matters more difficult, the SMS port number must be embedded into the body of the message, and if you employ some type of message security (see the Security considerations with messages section), your data length will be even less. Still, with a delicate combination of live data from the incoming message and predefined application elements, you should be able to transmit a meaningful message to the user and invoke special application functions all within one message.


 


Emulators


In the J2ME/mobile Java space, working with the various emulators from the different OEMs, as well as Sun’s Wireless Toolkit (WTK), is typically a hit or miss situation. While an emulator may excel at one set of functions, it may completely crash or throw a litany of exceptions when asked to perform other functions. Thus, it’s always good to keep a handful of emulators around when debugging and testing.


For myself, I found the WTK to work well for testing the WMA and Push Registry functions. The WTK has a feature to send SMS and CBS messages to the emulator; the messages can either be text or binary. The project I was involved with involved one specific phone which handed only binary messages to the Java layer. That is, only instances of javax.wireless.messaging.BinaryMessage were passed to the application, and attempts to cast the incoming message to a javax.wireless.messaging.TextMessage threw a ClassCastException. Thus I needed to pass binary to the emulator, which it in turn passed to the application. The WTK only sends binaries via a file that is written on the hard disk, so to test the J2ME application, I wrote a small Java program to write binary data to a file on the hard disk. Of course, the format of the binary file matched the format that my a J2ME application was expecting. Then I used the WTK to send that binary to the emulator, at which point it could be read and parsed inside my application. This method proved to be a reliable test when compared to the operation of the device.


The Nokia emulators also support the WMA, and others may as well, so instead of using the “Default Color Phone” emulator with the WTK, you can setup the WTK to use the Nokia (or other OEM) emulators. Admittedly, I found the interaction between the WTK and non-WTK emulators a little lacking when using advanced functionality, so I decided to stick with the WTK’s “Default Color Phone” emulator most of the time. Furthermore, the skin for the “Default Color Phone” emulator of the WTK 2.1 seems to impress non-technical types, so you may get extra “ooos” and “ahhs” from the bosses above.


To use the WTK for WMA/Push Registry testing, though, you must “install” the application via OTA to emulator, instead of just clicking “Run”. To install via OTA, select “Run via OTA” from the Project menu. The process is simple; just follow the screens in the emulator. When you are done, the application will appear to the emulator as if it had been installed OTA, and you can use functions like the WMA and Push Registry easily. Both functions can be invoked from the WTK’s WMA console (File – > Utilities, click “Open Console” in the WMA section of the window). Text messages are easy to push to the emulator, but if your real world device only allows you BinaryMessage instances, pass the emulator a file containing the binary payload data you want to send.


 


Conclusion


The issues involved with getting a WMA/Push Registry-enabled application to market can seem daunting, but the benefits are clearly worthwhile. Through these mechanisms you can have a much more dynamic interaction with your users to aide in customer retention and brand loyalty. The one truly important caveat is the varying costs of SMS traffic. Thus, the message must be completely relevant to user and their interaction with the application. Also, the user must have a way to opt-in and opt-out of messages they may receive from your company. With a well-conceived business model, users may consider it essential to receive messages on their device about your application or services.


 


 


Code Sample 1 – A simplified version of the message handling classes


 


class MessageListenerImpl implements MessageListener


{


public void notifyIncomingMessage(MessageConnection mCon)


{ messageReader.handleMessage(); }


}


 


class WirelessMessageReader implements Runnable


{


private boolean readMessages = true;


private int pendingMessages;


private MessageConnection msgConn = null;


 


public void run()


{


while(readMessages)


{


synchronized(this)


{


if(pendingMessages == 0)


{


try { wait(); }


catch(InterruptedException ie) {}


}



pendingMessages–;


}



Message message = null;



try


{


Message message = msgConn.receive();


/* parse payload */


}


catch(IOException ioe) {}


}


}



synchronized void handleMessage()


{


pendingMessages++;


notify();


}


}


 


Code Sample 2 – integration with the SimpleWire API.


 


import com.simplewire.sms.*;


 


public void sendSmsMessage(String msisdn, short msgPort)


{


SMS smsMessage = new SMS();


smsMessage.setSubscriberID(YOUR_SUBSCRIBER_ID);


smsMessage.setSubscriberPassword(YOUR_PASSWORD);


smsMessage.setMsgPin(“+1” + msisdn);


smsMessage.setDestPort(msgPort);


smsMessage.setMsgText(“Your msg here”);


smsMessage.msgSend();


}


 


 


 


——————————————————————————–


1.  Sony Ericsson, “Advanced Message Coding using JSR 120”, section 3.4.


2. Sun Microsystems, “Over The Air Initiated Provisioning Recommended Practice for the .Mobile Device Profile”


3. Sun Microsystems, Mobile Information Device Profile, v2.0 (JSR-118)


Developing Applications with the Java APIs for Bluetooth (JSR-82)

Developing Applications with the Java APIs for Bluetooth (JSR-82)



This paper covers the Java API for Bluetooth (JSR-82) with respect to Sony Ericsson devices. It starts by introducing the Bluetooth technology, followed by the Java APIs for Bluetooth, and how to use them.


Currently, these APIs are currently available in the Sony Ericsson P900/P908 handsets.


Click here to view “Developing Applications with the Java APIs for Bluetooth (JSR-82)”



Click here to view the Training Materials (.zip) associated with this article.


j2me:Socket connection

/*
J2ME: The Complete Reference


James Keogh

Publisher: McGraw-Hill

ISBN 0072227109

*/
// jad file (Please verify the jar size first)
/*
MIDlet-Name: socketconnection
MIDlet-Version: 1.0
MIDlet-Vendor: MyCompany
MIDlet-Jar-URL: socketconnection.jar
MIDlet-1: socketconnection, , socketconnection
MicroEdition-Configuration: CLDC-1.0
MicroEdition-Profile: MIDP-1.0
MIDlet-JAR-SIZE: 100

*/
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import java.io.*;
import javax.microedition.io.*;
public class socketconnection extends MIDlet implements CommandListener {
  private Command exit, start;
  private Display display;
  private Form form;
  public socketconnection () 
  {
    display = Display.getDisplay(this);
    exit = new Command(“Exit”, Command.EXIT, 1);
    start = new Command(“Start”, Command.EXIT, 1);
    form new Form(“Read Write Socket”);
    form.addCommand(exit);
    form.addCommand(start);
    form.setCommandListener(this);
  }
  public void startApp() throws MIDletStateChangeException 
  {
    display.setCurrent(form);
  }
  public void pauseApp() 
  {
  }
  public void destroyApp(boolean unconditional
  {
  }
  public void commandAction(Command command, Displayable displayable
  {
    if (command == exit
    {
      destroyApp(false);
      notifyDestroyed();
    }
    else if (command == start
    {
      try 
      {
       StreamConnection connection = (StreamConnectionConnector.open(“socket://www.myserver.com:80”);
       PrintStream output = 
         new PrintStream(connection.openOutputStream() );
       output.println“GET /my.html HTTP/0.9\n\n” );
       output.flush();
       InputStream in = connection.openInputStream();
       int ch;
       while( ( ch = in.read() ) != –)
      {
         System.out.print( (charch );
       }
       in.close();
       output.close();
       connection.close();
     }
      catchConnectionNotFoundException error )
       {
         Alert alert = new Alert(
            “Error”“Cannot access socket.”, null, null);
         alert.setTimeout(Alert.FOREVER);
         alert.setType(AlertType.ERROR);
         display.setCurrent(alert);      
        }
        catchIOException error )
        {
         Alert alert = new Alert(“Error”, error.toString(), null, null);
         alert.setTimeout(Alert.FOREVER);
         alert.setType(AlertType.ERROR);
         display.setCurrent(alert);
        }
    }
  }
}


Demonstrates the functionality of DatagramConnection framework.

/*** Chapter 5 Sample Code for Datagram functionality ***/

import 
javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.io.*;
import java.util.*;

public class DatagramTest extends MIDlet {

  // Port 9001 is used for datagram communication
    static final int receiveport  = 9001;
  Receive receiveThread = new Receive();

    public DatagramTest() {
  }

    public void startApp() {
        // Start the listening thread
        receiveThread.start();
        // Send message Hello World!
        sendMessage(“Hello World!”);
    }

    public void pauseApp() {
    }

    public void destroyApp(boolean unconditional)  {
    }

  // This function sends a datagram message on port 9001.
    void sendMessage(String msg)  {
    String destAddr = “datagram://localhost:” + receiveport;
        DatagramConnection dc = null;
    Datagram dgram;
    byte[] bMsg = msg.getBytes();

    try {
           dc = (DatagramConnection)Connector.open(destAddr);
      // Create a datagram socket and send
            dgram= dc.newDatagram(bMsg,bMsg.length,destAddr);
            dc.send(dgram);
      System.out.println(“Sending Packet:” +  msg);
            dc.close();
        }
        catch (Exception e)  {
            System.out.println(“Exception Connecting: ” + e.getMessage());
    }
    finally {
            if (dc != null) {
                try {
                    dc.close();
                }
                catch (Exception e) {
                   System.out.println(“Exception Closing: ” + e.getMessage());
                }
            }
        }
    }

  // This function is a listener. It waits to receive datagram packets on 9001 port
    class Receive extends Thread  {
        public void run() {
        doReceive();
        }

        void doReceive() {
            DatagramConnection dc = null;
            Datagram dgram;
      try {
        // Open Server side datagram connection
                dc = (DatagramConnection)Connector.open(“datagram://:”+receiveport);
          String receivedMsg;
          while (true) {
                    dgram = dc.newDatagram(dc.getMaximumLength());
                try {
             dc.receive(dgram);
          catch (Exception e) {
            System.out.println(“Exception in receiving message:” + e.getMessage());
          }
                    receivedMsg = new String(dgram.getData()0,dgram.getLength());
                    System.out.println(“Received Message: ” + receivedMsg);
                    try {
                       Thread.sleep(500);
                    }
                    catch (Exception e) {
                      System.out.println(“Exception doReceive(): ” + e.getMessage());
                    }
                }

            }
          catch (Exception e) {
          System.out.println(“Exception doReceive(): ” + e.getMessage());
       }
       finally {
          if (dc != null) {
          try {
                       dc.close();
                   }
                   catch (Exception e) {
                      System.out.println(“Exception Closing: ” + e.getMessage());
                   }
               }
          }

        }
     }
 }


How to write a shell script

How to write a shell script
Introduction
A shell is a command line interpretor. It takes commands and executes them. As such, it implements a programming language. The Bourne shell is used to create shell scripts — ie. programs that are interpreted/executed by the shell. You can write shell scripts with the C-shell; however, this is not covered here.


Creating a Script
Suppose you often type the command
    find . -name file -print


and you’d rather type a simple command, say
    sfind file


Create a shell script
    % cd ~/bin
    % emacs sfind
    % page sfind
    find . -name $1 -print
    % chmod a+x sfind
    % rehash
    % cd /usr/local/bin
    % sfind tcsh
    ./shells/tcsh


Observations
This quick example is far from adequate but some observations:
Shell scripts are simple text files created with an editor.
Shell scripts are marked as executeable
    %chmod a+x sfind


Should be located in your search path and ~/bin should be in your search path.
You likely need to rehash if you’re a Csh (tcsh) user (but not again when you login).
Arguments are passed from the command line and referenced. For example, as $1.
#!/bin/sh
All Bourne Shell scripts should begin with the sequence
    #!/bin/sh


From the man page for exec(2):
“On the first line of an interpreter script, following the “#!”, is the name of a program which should be used to interpret the contents of the file. For instance, if the first line contains “#! /bin/sh”, then the con- tents of the file are executed as a shell script.”


You can get away without this, but you shouldn’t. All good scripts state the interpretor explicitly. Long ago there was just one (the Bourne Shell) but these days there are many interpretors — Csh, Ksh, Bash, and others.


Comments
Comments are any text beginning with the pound (#) sign. A comment can start anywhere on a line and continue until the end of the line.
Search Path
All shell scripts should include a search path specifica- tion:
    PATH=/usr/ucb:/usr/bin:/bin; export PATH


A PATH specification is recommended — often times a script will fail for some people because they have a different or incomplete search path.
The Bourne Shell does not export environment variables to children unless explicitly instructed to do so by using the export command.


Argument Checking
A good shell script should verify that the arguments sup- plied (if any) are correct.


    if [ $# -ne 3 ]; then
         echo 1>&2 Usage: $0 19 Oct 91
         exit 127
    fi


This script requires three arguments and gripes accordingly.


Exit status
All Unix utilities should return an exit status.
    # is the year out of range for me?


    if [ $year -lt 1901  -o  $year -gt 2099 ]; then
         echo 1>&2 Year \”$year\” out of range
         exit 127
    fi


    etc…


    # All done, exit ok


    exit 0


A non-zero exit status indicates an error condition of some sort while a zero exit status indicates things worked as expected.
On BSD systems there’s been an attempt to categorize some of the more common exit status codes. See /usr/include/sysexits.h.


Using exit status
Exit codes are important for those who use your code. Many constructs test on the exit status of a command.
The conditional construct is:


    if command; then
         command
    fi


For example,
    if tty -s; then
         echo Enter text end with \^D
    fi


Your code should be written with the expectation that others will use it. Making sure you return a meaningful exit status will help.
Stdin, Stdout, Stderr
Standard input, output, and error are file descriptors 0, 1, and 2. Each has a particular role and should be used accordingly:
    # is the year out of range for me?


    if [ $year -lt 1901  -o  $year -gt 2099 ]; then
         echo 1>&2 Year \”$year\” out of my range
         exit 127
    fi


    etc…


    # ok, you have the number of days since Jan 1, …


    case `expr $days % 7` in
    0)
         echo Mon$$
    1)
         echo Tue$$


    etc…


Error messages should appear on stderr not on stdout! Output should appear on stdout. As for input/output dialogue:
    # give the fellow a chance to quit


    if tty -s ; then
         echo This will remove all files in $* since …
         echo $n Ok to procede? $c;      read ans
         case “$ans” in
              n*|N*)
    echo File purge abandoned;
    exit 0   $$
         esac
         RM=”rm -rfi”
    else
         RM=”rm -rf”
    fi


Note: this code behaves differently if there’s a user to communicate with (ie. if the standard input is a tty rather than a pipe, or file, or etc. See tty(1)).
Language Constructs
For loop iteration
Substitute values for variable and perform task:


    for variable in word …
    do
         command
    done


For example:
    for i in `cat $LOGS`
    do
            mv $i $i.$TODAY
            cp /dev/null $i
            chmod 664 $i
    done


Alternatively you may see:
    for variable in word …; do command; done


Case
Switch to statements depending on pattern match


    case word in
    [ pattern [ | pattern … ] )
         command $$ ] …
    esac


For example:


    case “$year” in


    [0-9][0-9])
            year=19${year}
            years=`expr $year – 1901`
            $$
    [0-9][0-9][0-9][0-9])
            years=`expr $year – 1901`
            $$
    *)
            echo 1>&2 Year \”$year\” out of range …
            exit 127
            $$
    esac


Conditional Execution
Test exit status of command and branch


    if command
    then
         command
    [ else
         command ]
    fi


For example:
    if [ $# -ne 3 ]; then
            echo 1>&2 Usage: $0 19 Oct 91
            exit 127
    fi


Alternatively you may see:
    if command; then command; [ else command; ] fi


While/Until Iteration
Repeat task while command returns good exit status.


    {while | until} command
    do
         command
    done


For example:
    # for each argument mentioned, purge that directory


    while [ $# -ge 1 ]; do
            _purge $1
            shift
    done


Alternatively you may see:
    while command; do command; done


Variables
Variables are sequences of letters, digits, or underscores beginning with a letter or underscore. To get the contents of a variable you must prepend the name with a $.


Numeric variables (eg. like $1, etc.) are positional vari- ables for argument communication.



Variable Assignment
Assign a value to a variable by variable=value. For example:


    PATH=/usr/ucb:/usr/bin:/bin; export PATH


or
    TODAY=`(set \`date\`; echo $1)`


Exporting Variables
Variables are not exported to children unless explicitly marked.


    # We MUST have a DISPLAY environment variable


    if [ “$DISPLAY” = “” ]; then
            if tty -s ; then
     echo “DISPLAY (`hostname`:0.0)? \c”;
     read DISPLAY
            fi
            if [ “$DISPLAY” = “” ]; then
     DISPLAY=`hostname`:0.0
            fi
            export DISPLAY
    fi


Likewise, for variables like the PRINTER which you want hon- ored by lpr(1). From a user’s .profile:
    PRINTER=PostScript; export PRINTER


Note: that the Cshell exports all environment variables.


Referencing Variables
Use $variable (or, if necessary, ${variable}) to reference the value.


    # Most user’s have a /bin of their own


    if [ “$USER” != “root” ]; then
            PATH=$HOME/bin:$PATH
    else
            PATH=/etc:/usr/etc:$PATH
    fi


The braces are required for concatenation constructs.
$p_01


The value of the variable “p_01”.
${p}_01


The value of the variable “p” with “_01” pasted onto the end.


Conditional Reference


${variable-word}


If the variable has been set, use it’s value, else use word.
POSTSCRIPT=${POSTSCRIPT-PostScript};
export POSTSCRIPT


${variable:-word}


If the variable has been set and is not null, use it’s value, else use word.
These are useful constructions for honoring the user envi- ronment. Ie. the user of the script can override variable assignments. Cf. programs like lpr(1) honor the PRINTER environment variable, you can do the same trick with your shell scripts.


${variable:?word}


If variable is set use it’s value, else print out word and exit. Useful for bailing out.


Arguments
Command line arguments to shell scripts are positional vari- ables:


$0, $1, …


The command and arguments. With $0 the command and the rest the arguments.
$#


The number of arguments.
$*, $@


All the arguments as a blank separated string. Watch out for “$*” vs. “$@”.
And, some commands:
shift


Shift the postional variables down one and decrement number of arguments.
set arg arg …


Set the positional variables to the argument list.
Command line parsing uses shift:


    # parse argument list


    while [ $# -ge 1 ]; do
            case $1 in
         process arguments…
            esac
            shift
    done


A use of the set command:
    # figure out what day it is


    TODAY=`(set \`date\`; echo $1)`


    cd $SPOOL


    for i in `cat $LOGS`
    do
            mv $i $i.$TODAY
            cp /dev/null $i
            chmod 664 $i
    done


Special Variables
$$


Current process id. This is very useful for constructing temporary files.
         tmp=/tmp/cal0$$
         trap “rm -f $tmp /tmp/cal1$$ /tmp/cal2$$”
         trap exit 1 2 13 15
         /usr/lib/calprog >$tmp


$?


The exit status of the last command.
         $command
         # Run target file if no errors and …


         if [ $? -eq 0 ]
         then
  etc…
         fi



Quotes/Special Characters
Special characters to terminate words:


      ; & ( ) | ^ < > new-line space tab


These are for command sequences, background jobs, etc. To quote any of these use a backslash (\) or bracket with quote marks (“” or ”).
Single Quotes


Within single quotes all characters are quoted — including the backslash. The result is one word.



         grep :${gid}: /etc/group | awk -F: ‘{print $1}’


Double Quotes
Within double quotes you have variable subsitution (ie. the dollar sign is interpreted) but no file name generation (ie. * and ? are quoted). The result is one word.


         if [ ! “${parent}” ]; then
           parent=${people}/${group}/${user}
         fi


Back Quotes
Back quotes mean run the command and substitute the output.



         if [ “`echo -n`” = “-n” ]; then
   n=””
   c=”\c”
         else
   n=”-n”
   c=””
         fi


and
         TODAY=`(set \`date\`; echo $1)`


Functions
Functions are a powerful feature that aren’t used often enough. Syntax is


    name ()
    {
         commands
    }


For example:


    # Purge a directory


    _purge()
    {
            # there had better be a directory


            if [ ! -d $1 ]; then
     echo $1: No such directory 1>&2
     return
            fi


         etc…
    }


Within a function the positional parmeters $0, $1, etc. are the arguments to the function (not the arguments to the script).
Within a function use return instead of exit.


Functions are good for encapsulations. You can pipe, redi- rect input, etc. to functions. For example:


    # deal with a file, add people one at a time


    do_file()
    {
            while parse_one


            etc…
    }


    etc…


    # take standard input (or a specified file) and do it.


    if [ “$1” != “” ]; then
            cat $1 | do_file
    else
            do_file
    fi


Sourcing commands
You can execute shell scripts from within shell scripts. A couple of choices:


sh command


This runs the shell script as a separate shell. For example, on Sun machines in /etc/rc:


         sh /etc/rc.local


. command
This runs the shell script from within the current shell script. For example:


         # Read in configuration information
         .  /etc/hostconfig


What are the virtues of each? What’s the difference? The second form is useful for configuration files where environment variable are set for the script. For example:
    for HOST in $HOSTS; do


      # is there a config file for this host?


      if [ -r ${BACKUPHOME}/${HOST} ]; then
.  ${BACKUPHOME}/${HOST}
      fi
    etc…


Using configuration files in this manner makes it possible to write scripts that are automatically tailored for differ- ent situations.
Some Tricks
Test
The most powerful command is test(1).


    if test expression; then


         etc…


and (note the matching bracket argument)
    if [ expression ]; then


         etc…


On System V machines this is a builtin (check out the com- mand /bin/test).
On BSD systems (like the Suns) compare the command /usr/bin/test with /usr/bin/[.


Useful expressions are:


test { -w, -r, -x, -s, … } filename


is file writeable, readable, executeable, empty, etc?
test n1 { -eq, -ne, -gt, … } n2


are numbers equal, not equal, greater than, etc.?
test s1 { =, != } s2


Are strings the same or different?
test cond1 { -o, -a } cond2


Binary or; binary and; use ! for unary negation.
For example


    if [ $year -lt 1901  -o  $year -gt 2099 ]; then
         echo 1>&2 Year \”$year\” out of range
         exit 127
    fi


Learn this command inside out! It does a lot for you.


String matching
The test command provides limited string matching tests. A more powerful trick is to match strings with the case switch.


    # parse argument list


    while [ $# -ge 1 ]; do
            case $1 in
            -c*)    rate=`echo $1 | cut -c3-`$$
            -c)     shift;  rate=$1 $$
            -p*)    prefix=`echo $1 | cut -c3-`$$
            -p)     shift;  prefix=$1 $$
            -*)     echo $Usage; exit 1 $$
            *)      disks=$*;       break   $$
            esac


            shift


    done


Of course getopt would work much better.


SysV vs BSD echo
On BSD systems to get a prompt you’d say:


    echo -n Ok to procede?;  read ans


On SysV systems you’d say:
    echo Ok to procede? \c; read ans


In an effort to produce portable code we’ve been using:
    # figure out what kind of echo to use


    if [ “`echo -n`” = “-n” ]; then
            n=””;  c=”\c”
    else
            n=”-n”;     c=””
    fi


    etc…


    echo $n Ok to procede? $c; read ans


Is there a person?
The Unix tradition is that programs should execute as qui- etly as possible. Especially for pipelines, cron jobs, etc.


User prompts aren’t required if there’s no user.


    # If there’s a person out there, prod him a bit.


    if tty -s; then
         echo Enter text end with \^D
    fi


The tradition also extends to output.
    # If the output is to a terminal, be verbose


    if tty -s <&1; then
         verbose=true
    else
         verbose=false
    fi


Beware: just because stdin is a tty that doesn’t mean that stdout is too. User prompts should be directed to the user terminal.
    # If there’s a person out there, prod him a bit.


    if tty -s; then
         echo Enter text end with \^D >&0
    fi


Have you ever had a program stop waiting for keyboard input when the output is directed elsewhere?


Creating Input
We’re familiar with redirecting input. For example:


    # take standard input (or a specified file) and do it.


    if [ “$1” != “” ]; then
            cat $1 | do_file
    else
            do_file
    fi


alternatively, redirection from a file:
    # take standard input (or a specified file) and do it.


    if [ “$1” != “” ]; then
            do_file < $1
    else
            do_file
    fi


You can also construct files on the fly.
    rmail bsmtp <
    rcpt to:
    data
    from: <[email protected]>
    to:
    Subject: Signon $2


    subscribe $2 Usenet Feeder at UWO
    .
    quit
    EOF


Note: that variables are expanded in the input.


String Manipulations
One of the more common things you’ll need to do is parse strings. Some tricks



    TIME=`date | cut -c12-19`


    TIME=`date | sed ‘s/.* .* .* \(.*\) .* .*/\1/’`


    TIME=`date | awk ‘{print $4}’`


    TIME=`set \`date\`; echo $4`


    TIME=`date | (read u v w x y z; echo $x)`


With some care, redefining the input field separators can help.


    #!/bin/sh
    # convert IP number to in-addr.arpa name


    name()
    {    set `IFS=”.”;echo $1`
         echo $4.$3.$2.$1.in-addr.arpa
    }


    if [ $# -ne 1 ]; then
         echo 1>&2 Usage: bynum IP-address
         exit 127
    fi


    add=`name $1`


    nslookup < < EOF | grep “$add” | sed ‘s/.*= //’
    set type=any
    $add
    EOF


Debugging
The shell has a number of flags that make debugging easier:


sh -n command


Read the shell script but don’t execute the commands. IE. check syntax.


sh -x command


Display commands and arguments as they’re executed. In a lot of my shell scripts you’ll see


    # Uncomment the next line for testing
    # set -x


 

mysql backup shell script

mysql backup shell script
#!/bin/sh
# mysql_backup.sh: backup mysql databases and keep newest 5 days backup.
#
# Last updated: 2006.9.6
# ———————————————————————-
# This is a free shell script under GNU GPL version
# Feedback/comment/suggestions : http://www.strongd.net
# ———————————————————————-


# your mysql login information
# db_user is mysql username
# db_passwd is mysql password
# db_host is mysql host
# —————————–
db_user=”root”
db_passwd=”passwd”
db_host=”localhost”


# the directory for story your backup file.
backup_dir=”/backup”


# date format for backup file (dd-mm-yyyy)
time=”$(date +”%d-%m-%Y”)”


# mysql, mysqldump and some other bin’s path
MYSQL=”$(which mysql)”
MYSQLDUMP=”$(which mysqldump)”
MKDIR=”$(which mkdir)”
RM=”$(which rm)”
MV=”$(which mv)”
GZIP=”$(which gzip)”


# check the directory for store backup is writeable
test ! -w $backup_dir && echo “Error: $backup_dir is un-writeable.” && exit 0


# the directory for story the newest backup
test ! -d “$backup_dir/backup.0/” && $MKDIR “$backup_dir/backup.0/”


# get all databases
all_db=”$($MYSQL -u $db_user -h $db_host -p$db_passwd -Bse ‘show databases’)”


for db in $all_db
do
    $MYSQLDUMP -u $db_user -h $db_host -p$db_passwd $db | $GZIP -9 > “$backup_dir/backup.0/$time.$db.gz”
done


# delete the oldest backup
test -d “$backup_dir/backup.5/” && $RM -rf “$backup_dir/backup.5”


# rotate backup directory
for int in 4 3 2 1 0
do
    if(test -d “$backup_dir”/backup.”$int”)
    then
        next_int=`expr $int + 1`
        $MV “$backup_dir”/backup.”$int” “$backup_dir”/backup.”$next_int”
    fi
done


exit 0;