Popular posts

Pages

Showing posts with label development. Show all posts
Showing posts with label development. Show all posts

Saturday, October 8, 2016

Create a Windows service out of Java Program using Apache prunsrv / procrun

When I had to run a stand-alone Java application in the background, I used to run it with an "&" and push it to background in Linux. Then I scheduled a cron to check the program every hour and start it if it went dead. This helped me in most scenarios on Linux platform.

However, when I had to write an 'always on' Java application on Windows platform.. I didn't like the idea of an always open cmd console with program output running on it. What if someone closed the cmd window by mistake? What if the server got rebooted for any reason? Yes, to run a program in background I could use javaw.exe instead of java.exe to push it into background as I used to do in Linux. But it didn't appeal me much. Then I stumbled upon this cool thing Apache Commons procrun/prunsrv application to wrap around the program and create a Service out of it. It would run in background, and a service could be set to automatic start... elegant and perfect solution for my problem.

Here is how it got working for me after troubleshoot for many days...now I’m writing it down here, so nobody has to spend so much time again. Refer and use as you like.
  1. Download the prunsrv exe for Windows - link
  2. I had to modify my Main class to suite the prunsrv format, as initially I didn’t plan to use it.
a)      prunsrv.exe takes lot of arguments which you can study here.
b)      I have used the StartMethod and StopMethod as "main" itself, and the StartParams as "start" and StopParams as "stop". These params get passed to main as arg[0]. Now my program looks like below. Notice that 'stopServer()' is static method, that is important.
      public static void main(String[] args) throws Exception {
            EventServer server = new EventServer();
            if ("start".equals(args[0])) {
                 
                  // your program or calls etc etc.

            }
            if("stop".equals(args[0]))
                  stopServer();

      }
     
      public static void stopServer() {
            log(EventServer.class.getSimpleName() + " ENDING SERVER PROGRAM.");
            System.exit(0);
      }

  1. Contents of installapp.bat file, which I run in cmd prompt to install the service. It looks scary, but remember it is a single line. If you study the parameters, all are easily understood. Some parameters have different behavior to accept data like JvmOptions, which you can study on the commons page. Note that prunsrv.exe resides in folder windows\amd64, because my processor is amd64 (you can check by running the command "echo %PROCESSOR_ARCHITECTURE%")
  2. prunsrv.exe //IS//EventGridGateway --DisplayName="EventGridGateway" --Description="Event Grid Gateway" --Install="C:\Users\abhishek\Downloads\commons-daemon-1.0.15-bin-windows\amd64\prunsrv.exe" --Jvm="C:\Program Files\Java\jdk1.8.0_92\jre\bin\server\jvm.dll" --StartMode=jvm --StopMode=jvm --Startup=auto --StartClass=com.eventgridgateway.server.EventServer --StopClass=com.eventgridgateway.server.EventServer --StartParams=start --StopParams=stop --StartMethod=main --StopMethod=main --Classpath="D:\MyStuff\workspace_eclipse\eventgridgateway\target\gatewayserverv2.jar;D:\MyStuff\workspace_eclipse\eventgridgateway\target\bin\hsqldb-2.3.4.jar;D:\MyStuff\workspace_eclipse\eventgridgateway\target\bin\guava-19.0.jar;D:\MyStuff\workspace_eclipse\eventgridgateway\target\bin\sqljdbc41.jar" --JvmOptions=-Dprops="D:\MyStuff\workspace_eclipse\eventgridgateway\target\config.properties" --LogLevel=DEBUG --LogPath="D:\logs" --LogPrefix=procrun.log --StdOutput="D:\logs\stdout.log" --StdError="D:\logs\stderr.log"

  3. Once you run installapp.bat, and if everything is fine, Windows will install your service successfully. Search services.msc with name EventGridGateway. If you need to recreate the service, say any change in above command, first you need to uninstall the service using below command in cmd (Run as Administrator)
  4. After the service is setup, you can run it. For me, it took many attempt before it actually started. The log in D:\logs capture details regarding service and program output (system.out.print)

I have tested this on my machine which is Windows 8, with JRE 1.8




    Friday, November 29, 2013

    Awesome tutorial on Perl Hashes

    If you do programming in perl you know how useful Hashes are! Found this cool tutorial and I'm amazed to see so many ways in which Hashes can work for me.... check it out

    http://www.perl.com/pub/2006/11/02/all-about-hashes.html

    Saturday, September 7, 2013

    Regular expression in javascript / jquery

    In this small snippet I'm going to show usage regex in javascript (with jquery). I'm not going to explain the usage and importance of regex in programming. There are entire books written solely on regex :). All I can say is regex can be one of the most powerful tools in your coding toolkit.

    So here is the situation: I've got a website. A text <input> inside a form and drop-down <select> object. Now based on the change in <select> I want to replace some content in the <input> text value.

    HTML
    <select>
        <option value="SEV2/min">sev2/min</option>
        <option value="SEV3/maj">sev3/maj</option>
        <option value="SEV4/cri">sev4/cri</option>
    </select>
    <br>
    <input id="sms" type="text" value="bharti, sev: SEV2/min,circle: bihar,impact: voice" />

    JS
    var re = /sev:\sSEV\d\/[a-zA-Z]+,/;
    $("select").on('change',function(){
        var newsev =  $(this).val();
        var text = $("#sms").val();
       
        var newtext = text.replace ( re, "sev: " + newsev + "," );
        $("#sms").val( newtext );
    });

    Once the <select> is changed, the 'sms' text becomes for ex:

    [bharti, sev: SEV4/cri,circle: bihar,impact: voice]

    jsfiddle link: here

    The html is straight forward. Coming to JS now, here is the sequence:
    - define a 're' variable which will be our regular-expression PATTERN
    - get the value of <select> drop-down, everytime it is changed
    - get the text value of "sms" element.
    - populate a variable 'newtext' using the function str.replace( re-pattern, "new string" ). The replace takes two arguments. first, the pattern 're' (or actual string, eg: "sev4"), and second the string to replace matched text. After this call, the 'newtext' contains the updated string.
    - set the value of 'sms' element to 'newtext'

    This is all about replace(re,"new str") function, hope you enjoyed it!

    Sunday, July 28, 2013

    Autorefresh page (or form submission) using jQuery

    In this post you'll see how 'auto-refresh' feature can be put in a web-page (JSP here) or a form submission.

    HTML
    <span id="spanautorefresh">Refresh in:&nbsp;<label id="clock"></label>&nbsp;</span>

    Above HTML is placed in some part of the page for user to know when the page is going to refresh. We'll use the 'clock' label to display remaining seconds to refresh.

    jQuery
    In our $(document).ready(function(){});, we'll put our jquery function which goes like below

    // base functionality start
        var refresh=false;
        var refreshinterval=parseInt(60);
        clock = $("#clock").text(refreshinterval);


        var refreshfn = function autorefresh() {
            if(refresh) {
                var sec = parseInt(clock.text());
                sec = sec - parseInt(1);
                clock.text(sec);
                if(sec<1) {

                  clock.text(refreshinterval);
                  makeRequest();
                  //window.location.reload();
                }
            }
        }; 


    setInterval( refreshfn, 1000);

    // base functionality ends


    //Below 'click' handle is to 'pause' the timer
        $("#spanautorefresh").on('click',function() {
            if(refresh) refresh=false; else refresh=true;
        });


    Now lets go through the code. First two lines are used to set the variables for status (refresh=false) and refreshInterval (in our case 60 seconds). Next we're storing the 'clock' label in clock variable for future use. The actual magic is done by the variable 'refreshfn', which is our function. Since we've set the refresh variable as 'false', as the page loads for the first time the timer is off. Once the user clicks on the span (which houses clock) the refresh variable is set to true.
    The function 'setInterval( fn_name, milliSeconds ) is standard JS function which invokes the fn_name every milliSeconds ms. In our case it invokes refreshfn every 1000 ms or 1s. When this happens refreshfn is called and if refresh is 'true', the value of clock is reduced by 1. The IF block inside refreshfn checks the text value and if it is less than 1, a> sets the clock text back to 60, and b> calls makeRequest() function in this case. For standard auto-refresh, simply call the window.location.reload() JS function. In this case makeRequest() is doing jquery AJAX/POST request, sending a form data to page X and getting some values to populate a DIV element in current page.

    Auto refresh can also be enabled in standard JSP using response headers. But jquery gives you much more control over the functionality and can be triggered by user's action and page state.

    I hope you find this functionality useful and easy to implement!

    Thursday, September 27, 2012

    Perl program using HTTP Microsoft Translator API

    Code


    ## LWP for bing translator

    #use strict;
    use LWP::UserAgent;
    use URI::Escape;


    $browser = LWP::UserAgent->new();

    ## 1 Prepare for POST query with your application registration details

    $url = "https://datamarket.accesscontrol.windows.net/v2/OAuth2-13";
    $client_id = "YOUR-CLIENT-ID";
    $client_secret = "YOUR-KEY";
    $scope = "http://api.microsofttranslator.com";       # fixed
    $grant_type = "client_credentials";                  # fixed

    ## POST request for the 'token'
    $response = $browser->post( $url,
        [
            'client_id' => $client_id,
            'client_secret' => $client_secret,
            'scope' => $scope,
            'grant_type' => $grant_type
        ],
    );

    ## Token received is in JSON format, but I've treated it as a string
    ## and parsed it using pattern matching.

    my $content = $response->content;

    @array = split(/,/,$content);
    $var = $array[1];
    $var =~ /"(.*)":"(.*)"/;
    $token = uri_escape("Bearer " . $2);
    print "Token is ", $token, "\n\n";

    print "Sending text for translation\n";

    ## Text to be translated.

    $text = uri_escape("This is my life.");

    ## 2 Prepare the URL for the GET request, with 'to' language and other parameters.

    $url2 = "http://api.microsofttranslator.com/V2/Http.svc/Translate?text=" .     $text .
            "&to=" . "de" .
            "&appId=" . $token .
            "&contentType=text/plain";

    $resp2 = $browser->get ($url2, 'Authorization' => $token);

    ## Here you get the translated string with some tags, which you can parse as per your wish
    $value = $resp2->content;
    print "\nTranslated text is ", $value;

    Output


    Sending text for translation
    Translated text is <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">Das ist mein Leben.</string>

    Explanation

    The above Perl code uses the Microsoft Translator API to convert text from one language to other language. Here is the link for the application http://www.bing.com/translator/.
    Microsoft has provided couple of ways to use the API. Here, I've used the HTTP API in Perl, because well, that is what I know :p.

    So first, you need to register yourself on Windows Azure Marketplace, then register your application (a simple entry) to get your KEY.
    How this works is, every time you want to run your program to use the API, you request for a 'token' as a POST HTTP request. This token is valid for 10 minutes. Within this 10 minutes your program can use this token to make any text translation request.
    Once you receive the token, make a GET request using this token and the return you get is a translated text.
    The reason that I'm writing this, is because the documentation on MS site is not clear at all. I really liked the google implementation, it was straight forward. But then it became paid. I guess all good things come to an end after all.
    You can explore more on the MS site http://msdn.microsoft.com/en-us/library/hh454950.aspx. Hope you find this interesting!

    Sunday, February 27, 2011

    do the new

    Road less travelled
    this is my first post and the feeling is very new...i guess thats how it feels when one introspects (i've been told, its a good thing). haven't done that lately...but hey..better late than never :)
    every now and then we hit a stage when our interests come in the way of our "daily life". that is when we have the opportunity to grab it and think about it, work upon it and feel happy(satisfied, rejuvinated, and other nice adjectives). this time again, i've got an opportunity to explore my very old interest development. just started learning cgi/perl. i just love coding :D will keep posting about how it goes. till then, bis bald!