Popular posts

Pages

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




    Saturday, March 7, 2015

    DB2 GRANT privilege example

    Scenario: Suppose you have a database table and now an external application wants to connect to your database and read/view the records of this table.

    Approach: For the external application create a separate user and grant only the SELECT access to this table. This way your access is controlled and there is no chance of an inadvertent update/insert by the new-user

    Here are the steps:
    1. Create a local user on the db2 machine for external application to connect. If you have a db2 user group on the machine, add this user to it and try to connect to your database. Once you are able to connect, proceed to next step.
    2. With the new-user, run a select command on the needed table. DB2 will throw authorization error and should not return any rows since access is not granted to the new user.
      • db2 select count(*) <schema_owner_name>.MyTable.
    3. Open another terminal and connect to you database with the admin user.
    4. With your admin user, issue the GRANT command to new-user:
      • db2 grant select on table MyTable to user NewUser.
    5.  From the first terminal, again issue a select query from step 2. This time you should be able to see something returned.

    Login with new-user, and result of select query before the grant was given



    Login with admin user, the table COMPANY in database AD, and the GRANT statement

     


    After the grant was given



    For revoking the access use below command:
    db2 revoke select on table company from user ab844900

    I've successfully tested these commands on these environments
    1. DB2 10.5 Express C on Windows 7
    2. DB2 10.1 Enterprise on Windows 2008 Server Standard Edition R2

    NOTE:
    1. Test all database commands in a development/test environment prior to running on Prod. Always!!
    2. No matter how certain you are, make sure you have access to a database specialist in-case of trouble :)

    There are plethora of options with GRANT like insert,update,alter table. Refer the IBM DB2 documentation here
     http://www-01.ibm.com/support/knowledgecenter/SSEPEK_10.0.0/com.ibm.db2z10.doc.sqlref/src/tpc/db2z_sql_granttableorviewprivileges.dita

    Good luck!

    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!

    Thursday, August 15, 2013

    Java Web Start error - unable to launch the application

    While going through some online java tutorials (at oracle) I found two ways of running them. 1> Java Web Start, 2> Copy the code onto your computer and compile.
    Java Web Start is the latest technology where java code at server will run on your laptop. I was going through 'Swing' (GUI/browser) tutorials and I selected option 1.
    Now when the 'jnpl' file is downloaded on your machine, it invokes the required JRE and will try to run the program.

    The problem I was facing is, when trying to execute the JNPL file, I was getting error 'unable to launch the application' and in 'details tab' I found that it was unable to find JRE1.7, even while I've got the needed jre installed. To find out your installed jre version, on cmd type 'java -version'. This problem was stopping me from running tutorials using Java Web Start.

    Below solution worked for me (windows 7)
    1> Control Panel > Java icon
    2> General tab > Temporary Internet Files > Settings. This will pop-up a window with 'Delete Files' button. Delete the pre-selected two options.
    This should work generally, but my problem still persisted. Then proceed to 3
    3> In step 2, copy the Location of temporary files. (for me: C:\Users\IBM_ADMIN\AppData\LocalLow\Sun\Java\Deployment\cache) and go to that folder.
    4> Delete whatever is there. For me, there was a folder '6.0', maybe because I've another JRE1.6 running on my machine.
    5> Once I deleted this folder, and again tried running the JNPL file it worked flawless for me!

    Hope this works for you too!

    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!

    Saturday, March 30, 2013

    Taking the road ahead

    Quite often, while making a decision, I find myself in deep thought over the available options. This is not uncommon, given the fact that life today throws at us a plethora of choices...
    Its not wrong to think, not at all. And that decision, however small, still affects our life. Sometimes for a short while, choosing to go for a boring movie, or an year, buying a pair of super comfy shoes. Or for the whole life, say deciding over a life partner.

    The problem here is, some of us (myself included), waste an extraordinary huge amount of time to decide over things. Most of the time, things that are not worth giving a tenth of the time they stole. We take our sweet time and keep meditating on them. What we forget in this process is, total time that we have is limited. Which makes it imperative, that we make most of the available time. Now if we spend more time on deciding whether to take choice A or B, where is the time left to exercise/enjoy the outcome of our decision, or maybe to rectify? For every one second added to the decision making process, one second is deducted from the time we could have utilized our life after that decision.

    So, to maximize the available time, we need to allocate the right amount of time to decision-making and move on. We just cannot endlessly keep the decision open. But a question arises, if I take a hurried decision, would that not affect the quality of it? Isn't that risky? That was my way of thinking too. I would rather keep the decision open, than to choose an option which did not have 100% of my heart. Unfortunately it is the wrong approach. One, precious time is wasted. Two, the whole purpose that decision came to me, at that precise time was because it would have brought a value-add to me and my life at that point in time. When I keep the decision pending for a long time, that value diminishes gradually. So whole of that exercise becomes a waste.

    The answer is: we have to take a leap of faith. Even if a single option does not emerge as the "winner", we must go with the one which seems to be closest, and trust our instincts. Anyway, even after much deliberation we could not conclude, which means there are (and will be) unknowns involved. So its better to take the leap, free our mental energy and concentrate towards other meaningful stuff. Because while that decision is open, we are unable to live life to the maximum. When we make this decision with this approach, suddenly everything changes. The situation comes under our control. The time we were about to spend further deciding, we can now utilize to drive our actions in favor of the selected option and make most of our life. This single fact, truly means a lot. Its like, once we take this decision, it brings us back into the game, where moving ahead is the mantra, and stopping is game-over.