Monday, August 31, 2020

Pyenv Commands Quick Reference

 Recently, I've been spending more time learning Python as it's the core language used in the framework that we'll be building on. Similar to using docker to containerize apps or vm's to isolate the app env from messing up the local m/c, python provide's various options to isolate the development environment. One such tool is pyenv. It's such an effective tool that makes life much easier, especially when you're working with multiple python projects that may require different dependencies and different versions of one or more python modules. 

Here, I've listed out most of the pyenv commands I used to work around different projects in my development env: 


- To list versions that match a pattern

$ pyenv install --list | grep " 3\.[678]"


- To install a specific version

$ pyenv install 3.8.2


- To uninstall a specific version

$ pyenv uninstall 3.8.2


- Installation Location

$ ls ~/.pyenv/versions


- To list all available python versions

$ pyenv versions


- To list all pyenv commands

$ pyenv commands


- To set a python version globally

$ pyenv global 3.8.2


- To set a python version locally

$ pyenv local 3.8.2


- To set a python version current shell

$ pyenv shell 3.8.2


- Creating virtual environments

$ pyenv virtualenv 3.8.2 <env_name>


- Activating pyenv env (if necessary)

$ pyenv activate <env_name>

$ pyenv deactivate


Monday, March 9, 2020

Running Jenkins docker image with local file system mapped

Step 1: Pull down the Jenkins Docker Image from DockerHub: 


       docker pull jenkins/jenkins:latest

Note: You'll get the latest Jenkins image from jenkins/jenkins tag and not the official jenkins repo. Official one at the time when I downloaded was still referring to 2.60.3 version, whereas the jenkins/jenkins one was using 2.224. If you use the older version, certain plugins may not load properly.

Step 2: Create a local volume


       docker volume create jenkins-data

Step 3: Run Jenkins docker image with this local volume mapped to the jenkin container's path. 


      docker run --name jenkins \
           --d \
           -p 49001:8080 \
           -v jenkins-data:/var/jenkins_home \
           jenkins/jenkins:latest

Note: If you run into the following error:

/usr/local/bin/jenkins.sh: line 25: /var/jenkins_home/copy_reference_file.log: Permission denied

You will then need to give the correct permissions to the local directory which will be mapped to the containers path.

      sudo chown 1000 jenkins-data

Finally, when the container starts, you can access Jenkins Home by going to http://localhost:49001
When you access it for the first time, it'll ask for the admin password to be entered, which can be found from the logs or from $JENKINS_HOME/secrets/initialAdminPassword file.

      docker exec jenkins bash -c 'cat $JENKINS_HOME/secrets/initialAdminPassword'

Sunday, January 10, 2016

PostgreSQL 9.3 tidbits


Just came across an article that listed some of the cool new features of postgresql database. I've listed out some of those that I liked and thought might be useful...

  • pg_isready - New command-line utility to test whether a server is ready to accept connections.
$ pg_isready -p 5432 -h localhost
localhost:5432 - accepting connections

  • \watch - Allows convenient re-execution of queries. 
postgres=# SELECT datname, query, usename FROM pg_stat_activity ORDER BY query_start DESC LIMIT 1; \watch 60

  • \conninfo - Displays current connection information

postgres=# \conninfo
You are connected to database "postgres" as user "postgres" via socket in "/tmp" at port "5432".

  • \l - List Databases
postgres=# \l
                                  List of databases
        Name         |  Owner   | Encoding | Collate | Ctype |   Access privileges
---------------------+----------+----------+---------+-------+-----------------------
 arts_v6             | postgres | UTF8     | C       | C     |
 enact_recreate_test | postgres | UTF8     | C       | C     |
 postgres            | postgres | UTF8     | C       | C     |
 quarrysb_13_0_0     | postgres | UTF8     | C       | C     |
 template0           | postgres | UTF8     | C       | C     | =c/postgres          +
                     |          |          |         |       | postgres=CTc/postgres
 template1           | postgres | UTF8     | C       | C     | =c/postgres          +
                     |          |          |         |       | postgres=CTc/postgres
(6 rows)




Installation and Setup of PostgreSQL in Ubuntu


First, install postgresql and commonly used add-on's. 


> sudo apt-get install postgresql postgresql-contrib
 
If you plan to use the pgAdmin tool as the GUI front-end for your database, then execute 
the following command: 

> sudo apt-get install pgadmin3
 
The basic installation creates a "postgres" user as the root user to access PostgreSQL. 
But it doesn't setup an password. So we'll have to setup a password for this user.
 
> sudo -u postgres psql postgres 
 
Set a password for the "postgres" database role using the command: 
 
# \password postgres 
 
You're all set up to play around and start using PostgreSQL in your linux environment now!
 

Create a database by running "createdb" command:

> sudo -u postgres createdb
 
If you have an import sql script, you can load that by running 
 
> sudo -u postgres psql <  

You can also execute sql commands by simply starting up the sql console via 

> psql

followed by 
# create database 
... 
 
 
To allow connections to your database server, you'd probably have to make a minor change to 
your pg_hba.conf file. 
 
Replace "peer" with "md5" in the following line in your 
/etc/postgresql/9.3/main/pg_hba.conf file: 
 
# Database administrative login by Unix domain socket
local    all       postgres                           peer

Reload the configuration changes for it to be effective:

> sudo /etc/init.d/postgresql reload

To enable postgresql to listen across networks other than local, modify the listen_address 
in the following file:

/etc/postgresql/current/main/postgresql.conf [listen_address = '*']
 

Sunday, February 3, 2013

iTerm2 - Where are my colors?



I was badly missing my colors from iTerm console and this is how doldrum they looked in black/white regardless of what color profile I picked...

                                 
The boring one...          


 After some googling, found these 3 nice little exports that did the trick for me.
Just copy the following exports to your .profile file and voila! Your console comes back to life with beaming colors.. just the way you'd want it to.

export TERM=xterm-color
export CLICOLOR=1
export LSCOLORS=ExFxCxDxBxegedabagacad


The 'not so boring anymore' one...















Saturday, September 29, 2012

Git Headache Solved: 'Modified Files'


Pretty much all the dev team work on a mac environment except one! No rewards for guessing that its mine which differed from everyone else's. I occasionally use my Windows 7 box to do some development and commit to repo.
We opted to use git for this project and I have to say that the first few days were quite challenging to use git in the way its meant to be used. But after few hiccups we got the hang of it. I initially had some trouble setting up git on my windows m/c to behave the same way as on my mac. When I did a clone for a git repository a whole bunch of 'Modified' files showed up when I ran 'git status'. After some googling and tweaking the core.autocrlf setting to 'true/false/input', I got it working right. All the 'Modified Files' list disappeared. But recently I decided to look around for git clients for windows and installed git extensions and smartgit. But something changed and when I did a clone, the dreaded 'Modified Files' reared its head again! I thought "Ah! Thats a cakewalk. I know what to do" and started changing my core.autocrlf setting.. but nothing changed. When you run 'git config -l', you might see a bunch of core.autocrlf entries.. I ran the following to make sure every core.autocrlf entries are set to false:

> git config -l
> git config --global core.autocrlf false
> git config core.autocrlf false
> git config --system core.autocrlf false

Followed by
> git reset --hard
> git status

I still kept getting the 'Modified Files'. Strangely, when I ran the 'git status' from cygwin, it was fine. It showed no modified files. Cygwin git was 1.6.x version, whereas the one run from MingW was 1.7.4
After an invisible hand slapped the back of my head, I realized that I could run diff to see what the changes were.
> git diff 

This showed that the file contents were fine.. it was the mode that was the problem.
All the files showed the following:

old mode 100755  (rwx r-x r-x)
new mode 100644 (rw- r-- r--)

Not sure why it decided to do that, but changing the core.filemode solved this problem.
> git config core.filemode false

So when you run into a 'Modified Files' issue, make sure you check the setting for

core.autocrlf
core.safecrlf
core.filemode

Good Luck!

Friday, September 28, 2012

Hibernate Criteria Snippets



The very basic
session.createCriteria(Car.class);

session.createCriteria(Car.class)
.add(Restrictions.eq(“engine.code”, code))
.uniqueResult();

Collections: isEmpty(), size()
session.createCriteria(Student.class)
         .add(Restrictions.isEmpty(“courses”, 2));

Ignore case:
session.createCriteria(Student.class)
         .add(Restrictions.eq(“name”, name).ignoreCase());

session.createCriteria(Student.class)
         .add(Restrictions.ilike(“name”, name));


Wildcard:
session.createCriteria(Student.class)
         .add(Restrictions.like(“name”, “test%”));

session.createCriteria(Student.class)
         .add(Restrictions.like(“name”, “test”, MatchMode.START));


Logical Operations:
session.createCriteria(Student.class)
         .add(Restrictions.or(
                  Restrictions.and(
                           Restrictions.eq(“firstname”, fn), Restrictions.eq(“lastname”, ln)
                  ),
                  Restrictions.in(“subject”, subjects)
         ));

Projections & Transformers:
session.createCriteria(Student.class)
         .setProjection(Projections.projectionList()
                  .add(Projections.property(“name”).as(“studentName”))
                  .add(Projections.property(“section”).as(“section”)))
         .setResultTransformer(Transformers.aliasToBean(StudentDTO.class));


Aggregation:
session.createCriteria(Order.class)
         .setProjection(Projections.projectionList()
                  .add(Property.forName(“id”).group())
                  .add(Property.forName(“style”).count())
                  .add(Property.forName(“amount”).avg()));

SqlProjections:
String sql = “(select avg(o.amount) from Orders o where o.id= order_id) as avgAmount”;
session.createCriteria(Receipt.class)
         .createAlias(“orders”, “o”)
         .setProjection(Projections.projectionList()
                  .add(Projections.groupProperty(“o.id”))
                  .add(Projections.sqlProjection(
                           sql,
new String[]{“avgAmount”},
new Type[]{new BigDecimalType()})));


Conjunction & Disjunction:
Criteria criteria = session.createCriteria(Order.class);
Conjunction contact1Filter = Restrictions.conjunction();
      contact1Filter.add(Restrictions.eq("c1_firstname", c1fn));
      contact1Filter.add(Restrictions.eq("c1_lastname", c1ln));


Conjunction contact2Filter = Restrictions.conjunction();
      contact2Filter.add(Restrictions.eq("c2_firstname", c2fn));
      contact2Filter.add(Restrictions.eq("c2_lastname", c2ln));

Disjunction contact1Or2Filter = Restrictions.disjunction();
      contact1Or2Filter.add(contact1Filter);
      contact1Or2Filter.add(contact2Filter);

criteria.add(contact1Or2Filter);

... results in >>
 FROM Order WHERE 
  (c1_firstname AND c1_lastname)  -- conjunction 
     OR                           -- disjunction
  (c2_firstname AND c2_lastname)  -- conjunction


Friday, August 31, 2012

JAXB - marshalling an entity with missing @XmlRootElement


I'm currently working on an application that needs to send/receive SOAP messages which are fairly large. With simple cases, I could simply use SoapUI to load the wsdl and execute tests for each of the operations defined for that service. But when it comes to actually invoking the service via application, things could becomes little bit murkier if you start getting SOAP faults instead of valid response.
I ran into such scenario and looking at the java code, everything looked OK. Next thing was to print out the xml payload to see whats going on.

To do that, I had to marshal the java object into xml using JAXBContext and pass it to a writer. Following code does that..


        JAXBContext jaxbContext;
        String xmlData = "";
        String type = obj.getClass().getName();
        try {
            StringWriter writer = new StringWriter();
            jaxbContext = JAXBContext.newInstance(obj.getClass());
            Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
            jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            jaxbMarshaller.marshal(obj, writer);
            xmlData = writer.toString();
            logger.debug(String.format("XML Representation of %s: \n%s", type, xmlData));
        } catch (JAXBException e) {
            logger.error(String.format("Unable to marshal %s: \n%s", type, e.getMessage()));
        }


But when I ran it, I got the following error:

javax.xml.bind.MarshalException - with linked exception: [com.sun.istack.SAXException2: unable to marshal type "com.company.model.Header" as an element because it is missing an @XmlRootElement annotation]

It was easily fixed by adding @XmlRootElement annotation to those entities that I was trying to marshal, but that wasnt a good solution, since I really shouldn't have to do that.
These entities were generated via Apache CXF's wsdl2java task and every time I run that, its going to overwrite the changes that I did. After some googling, found that there were two ways that a JAXB runtime can perform marshaling:
  1. By adding @XmlRootElement
  2. Using JAXBElement wrapper objects, where T is the type that you'd want to marshal. 

Second option was definitely the way for me to go here.. Made the appropriate change and voila! I got what I wanted w/o having to worry about manipulating the wsdl generated code. :)


        JAXBContext jaxbContext;
        String xmlData = "";
        try {
            StringWriter writer = new StringWriter();
            JAXBElement<Header> jaxbWrappedHeader =  objectFactory.createHeader(obj);
            jaxbContext = JAXBContext.newInstance(Header.class);
            Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
            jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            jaxbMarshaller.marshal(jaxbWrappedHeader, writer);
            xmlData = writer.toString();
            logger.debug(String.format("XML Representation of Header: \n%s", xmlData));
        } catch (JAXBException e) {
            logger.error(String.format("Unable to marshal Header: \n%s", e));
        }

Only downside to this was not being able to use generics..



Monday, June 4, 2012

Stopping a windows process


If you ever find yourself stuck (I was) with working on an old windows box and you dont have the benefits of using something better than the lame windows process explorer, here are some things that helped me out with force killing my process..


There were multiple instances of tomcat running on this box and there was no way to tell which .exe process belongs to the one I'm trying to stop.
To list just the tomcat instances, you could run the 'tasklist' command.


tasklist /fi "imagename eq tomcat5.exe"  (replace tomcat5.exe with whatever process you're looking for)




Now which one of those tomcat5.exe is mine?!!! 
Its ugly, but 'wmic' command would help you out to find out the specific tomcat5.exe process. 


wmic /output:C:\Processes.txt PROCESS get Caption,Commandline,Processid


This creates a Processes.txt file under C:\ which lists out all the processes and the binary executable path it was started from. 
After looking up this file, I was able to narrow it down to the specific PID 3868 and was able to kill it by running 


taskkill /f /pid 3868 


With something like Sysinternals Process Explorer, you wouldn't need to go through all this, but if you ever get stuck with some limitations.. then you could always use 'other' ways to get around! :)

Thursday, July 28, 2011

Changing color scheme and font settings in gvim




I like using vim for quickly loading a file for view/edit etc on my windows m/c. 
At work, with the monitors being 21" in size.. I wanted vim to open up on a larger frame, and also wanted to have some tweaks incorporated (font, color scheme, tab width, etc). I thought I'd simply have to edit my .vimrc from my home directory and voila.. everything should work. Well.. not quite. It works fine for my command line vi invocation from cygwin, but not when I open up from vim. After googling a bit, found few suggestions which satisfied my needs. All you have to do is to edit the _vimrc file which is located in you vim installation folder. For instance, C:\Program Files\Vim 
You can either edit it directly, or open up vim editor and goto Edit -> Startup Settings. Once opened, you can add the settings to the file. In my case, I added the following: 

set tabstop=4
set number
set lines=50
set columns=120

If you need to change the color scheme, chose the color scheme that you liked, and add the following to the _vimrc file:

:color morning

For font settings, choose the font that you like, then type 
:set guifont?
This will display the current font setting information. Note that down and set it to guifont in _vimrc.
Here's mine:

if has ('gui_running') 
 set guifont=Bitstream_Vera_Sans_Mono:h10:cANSI
endif

Happy vimming!! And thanks for those folks who put out this nice little tidbit about vim settings.. 

Wednesday, July 6, 2011

JSON Hiccups

This is my first entry into the JSON world and everything looked pretty straight-forward from the outset.
When the time came to dig in and use JSON and map it back to POJO's, issues started sprouting, but nothing too daunting or complicated.

Issue 1: I had to call a RESTful webservice which responds with application/json type. I dont have the JSON schema available and the JSON object is quite large (requiring quite a few classes and fields). Now I needed to generate the java classes, but couldnt figure out an easy way (like how you would generate classes using XML schema). I could lookup the json string and then create the Java classes manually, which is what I did for the simpler json responses..but for the larger responses, it didnt seem to be a smart way to go about. After some googling, found this wonderful link http://jsongen.byingtondesign.com/ which generates the java files for you if you could provide the url for the json request! What a time-saver?

Issue 2:  This time, I was getting a json string which didnt follow the standard syntax. All the property names were capitalized and some properties were just named '$'. While reading about the json mapping, I understood that badgerfish, when creating json string from xml schema generates '$' as the property name to represent the text between the xml element. ex:
XML: <customer>Arnold</customer> is represented as
JSON: {"$": "Arnold"}
But due to the capitalized property names, when I tried to use ObjectMapper.readValue(json, Class)...it fails due to the fact that its looking for a property with lowercase name. To overcome that, I then had to use @JsonProperty annotation on each property in java file to match the property name in json and everything went smooth after that.  

Issue 3: Some of the generated java files didnt include all the property names that were found in the json string. So when I tried to map the values from json into java objects, it failed with an org.codehaus.jackson.map.exc.UnrecognizedPropertyException. If you need that property, you'd have to add that in your generated java file. But assuming you dont need that property and you dont want to keep adding those fields which is not needed by your app, the simplest way is to disable the FAIL_ON_UNKNOWN_PROPERTIES feature in Jackson's deserialization config by calling:

ObjectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);

Monday, April 18, 2011

Maven Token Replacement

I've been trying to create a maven pom file that would do the same stuff that the current ant build file does. In the process, I've been able to learn some good stuff about Maven.
One thing I had to accommodate is the directory structure that we have, which unfortunately is not the same as maven's default. Once I got the basic stuff working, I wanted to try couple of things:

* Add profiles, so I can build the app for different environments
* Add tokens to files that can replaced during build process

To setup the profiles, I just had to add something like this:
<profiles>
  <profile>
    <id>dev</id>
    <activation>
      <activebydefault>true</activebydefault>
    </activation>
    <properties>
      <env.properties>dev.properties</env.properties>
    </properties>
  </profile>

  <profile>
    <id>sso</id>
    <properties>
      <env.properties>sso.properties</env.properties>

    </properties>
  </profile>
</profiles>

This can be part of the pom itself or it could be saved into a file called profiles.xml

To get the token replacement working, I ran into some trouble. First I tried using filters which is specifically meant for this purpose, or so I thought.

Add the filter:
<filters>
  <filter>dev.properties</filter>
</filters>


Enable the filter (w/o this, filtering wont work):
<resource>
  <filtering>true</filtering>
  <directory>src/main/webapp/WEB-INF</directory>
  <includes><include>web.xml</include></includes>
</resource>

This did replace the token specified in web.xml file, but filtering actually just copies the included resources to WEB-INF/classes after replacing the token. So filters were out and had to look for another option. Then I ran into maven-replacer-plugin which does exactly what I need to do.

<plugin>
  <groupid>com.google.code.maven-replacer-plugin</groupid>
  <artifactid>maven-replacer-plugin</artifactid>
  <version>1.3.5</version>
  <executions>
    <execution>
    <id>replaceAuth</id>
    <phase><b>package</b></phase>
    <goals>
      <goal>replace</goal>
    </goals>
    </execution>
  </executions>
  <configuration>
    <file>target/simple-webapp/WEB-INF/web.xml</file>
    <replacements>
      <replacement>
          <token>AUTH_METHOD</token>
          <value>${auth.method}</value>
      </replacement>
    </replacements>
  </configuration>
</plugin>

I first tried the 'prepare-pacakage' phase as mentioned in some forums, but the file that I need to run replacement on wasnt copied over to the target directory at that point. So the maven build fails. I had to use the 'package' phase to apply the token replacement.

But when I ran
> mvn package
the final war file didnt have the replacement applied, even though the file under exploded directory had replaced value. The reason for this being the war:war task was run before the replacer:replace task.

Back to the forums and found that I also had to use the maven-war-plugin to get this working.
<plugin>
  <groupid>org.apache.maven.plugins</groupid>
  <artifactid>maven-war-plugin</artifactid>
  <version>2.1.1</version>
  <executions>
    <execution>
      <phase>package</phase>
      <goals><goal>war</goal></goals>
      <configuration>
         <webxml>target/simple-webapp/WEB-INF/web.xml</webxml>
      </configuration>
    </execution>
  </executions>
</plugin>


The forums suggested that I had to use 'exploded' goal, but that didnt do the job for me. I had to use the 'war' goal and also added the webXml element that points to the modified file. This finally got what I wanted.. all the tokens replaced in the target directory and also in the final .war file.
Glad I got it working, but Im still uncertain about the impact of including webXml. Theoretically, I should've had this working without specifying the configuration portion. What if I have to modify a file other that web.xml? I'll edit this after I try that and if I gain any further understanding.

Update: 
Turns out that I really didnt need the <webXml> tag defined within the war plugin. But I did notice that that the war goal runs twice...once by default and once after the replacement. Another note to keep in mind is that since both the plugins (replacer & war) are bound to the same phase (package), the order is important. If the war runs before replacer, then the final war will not have the replaced values. So make sure that the replacer plugin comes AFTER the war plugin.

To replace multiple tokens:
Use the following config in replacer plugin ...

<configuration>
       <includes>
             <include>target/${project.build.finalName}/sample1.txt</include>
             <include>target/${project.build.finalName}/sample2.txt</include>
       </includes>
       <replacements>
               <replacement>
                        <token>token1</token>
                        <value>value1</value>
                </replacement>
                <replacement>
                        <token>token2</token>
                        <value>value2</value>
                </replacement>
        </replacements>                       
</configuration>

Externalize the tokens in a properties file:
Use maven properties plugin to load the properties file as shown below:

<plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>maven-properties-plugin</artifactId>
        <version>1.0-SNAPSHOT</version>
        <executions>
          <execution>
            <phase>initialize</phase>
            <goals>
              <goal>read-project-properties</goal>
            </goals>
            <configuration>
              <files>
                <file>etc/config/dev.properties</file>
              </files>
            </configuration>
          </execution>
        </executions>
</plugin>

Tuesday, April 27, 2010

Solaris Tuning

Few of the things that I learned while performing load tests on a Solaris box were quite interesting and informative. Though these might be archaic for some, it was refreshing to view the performance limitations of an application from a different angle, rather than the code related issues (inefficient queries, synchronization blocks that are used haphazardly, memory hoggers, etc).
I'll try to list some of them that I used on the Solaris box to get additional information. First one was pretty obvious, since when the load test was run, weblogic server starting coughing up IOException (too many open files).
Running ulimit command showed that the open files settings on the box was too low for a high load. 
> ulimit -a
...
file size (blocks)      unlimited
open files                256
stack size (kbytes)    8192
...
This number should be adjusted based on the load (# of users) and other processes running on the system.
> ulimit -n 1024
This number is applicable only for the current session. If it needs to be set permanently, then rlim_fd_max (default hard limit) needs to be set to that number and system will need to be rebooted to make this effective.
To view the current list of file descriptors used by a specific process, use:
> ls /proc//fd | wc -l

Another helpful command is prstat or top (if available) that displays the top most processes running on the server that utilizes the most CPU.
> prstat -a (displays the CPU intensive processes grouped by user)
> prstat -n 3 -c (limits to top 3 processes and prints below the previous line)

Next comes sar (System Activity Reporter). This command lets you view the system activity and the most interesting one for me was
> sar -u (which displays the CPU utilization activity)

Time   %usr(user)  %sys(system)  %wio(waiting for I/O)  %idle(inactive)
If you want to watch the CPU utilization for every minute for the next 10 minutes, use
> sar -u 60 10
If idle time is consistently 0 or very low, it indicates that the CPU is running short on resources. Also if the wait time is consistently high, it indicates that there could be some stuck threads or blocking threads.

vmstat is another command that provides virtual memory, disk, page and CPU information
It displays the run, blocked & swapped processes and typically you should not see a high number under 'blocked' queue for consecutive reads.

iostat displays the input/output statistics for each disk. If the r/s and w/s is consistently high along with %b (% of time spent on transactions), then the application needs to be tuned to use the io processes more effectively.

To summarize, following are the commands that helped/guided me to gain additional insight into my app:
  • ulimit
  • prstat
  • sar
  • vmstat
  • iostat

Wednesday, April 21, 2010

Remote Monitoring Using jconsole

Recently, we made an architectural change to our app which would store the search results in HttpSession for post-sorting options. To test the impact of this additional memory usage by the app, I had to run a load-test with few hundred users who'd perform random searches and their search results would be saved to their sessions. Locally I was easily able to set up jmx monitoring by adding the following to server start script:

@REM JConsole
set JAVA_OPTIONS=%JAVA_OPTIONS% -Dcom.sun.management.jmxremote -Xmanagement


But when I tried to do the same for the cluster (running on unix server) where I was going to perform the load test, I ran into minor hitch as the server was running on secure layer (https). After few tries..and reading a little bit more from sun site about jconsole setup, I got it working. Here's what I had to include in my managed server startup script:

# JMX Remote Monitoring Settings
JMX_PROPERTIES=" -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=${JMX_PORT} -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false"
export JMX_PROPERTIES


JMX_PORT - port for each managed server where jconsole should connect for jmx agent.

And on my laptop, I just had to fire of jconsole and enter the following under "Advanced" tab:

service:jmx:rmi:///jndi/rmi://<hostname>:<managed_server_port>/jmxrmi

.. and you are presented with a beautiful sight (or horrendous) based on how well your vm performs. :-)

Monday, December 15, 2008

Elapsed Time in ksh

Being a novice on shell programming (ksh & bash), I've been looking for something short and sweet that would tell me how much time was taken up for my build (ant) to complete. Printing out the time(s) at the beginning of the script and at the end is very simple.. but what I'd wanted to was to print out something like.. " application build took and was completed successfully at

Friday, July 11, 2008

Mylyn is awesome

When I was trying to install an update for an eclipse plugin, I noticed that there were couple of mylyn related stuff present and I had no idea where they came from.. but later realized that it was bundled along with eclipse europa and later versions. Didnt bother much that time.. but couple of days later, ran into a developerworks article that was talking about how mylyn makes you even more productive. That sprouted my curiosity and I took a dig into what it was about. Played around with it a little bit.. and Boy, was I glad to have run into mylyn! It REALLY DOES make you MUCH MORE productive and more focussed.
And its very simple to use as well.
All you need to do is create a new local task (if you dont have a repository setup) and give it a due date, schedule date (based on ur schedule) and a priority. Activate the task and thats pretty much it! From there on, any file that you open to work on are automatically associated with the currently active mylyn task.. and it also makes it easy on you by removing the files that were closed and that havent been edited, but opened for a long time. Another beauty is that it even associates (displays in package explorer) only the methods that were accessed, which means you dont have to really get lost with sorting through the various classes that are present in your project and even the numerous methods in a class that have no relevance to the task you're working on currently! Finally, since mylyn integrates with CVS, if you have eclipse hooked up to CVS, you'll see that when its time to checkin the changes, all the classes impacted by the task you worked on are automatically grouped for you, making it much easier to group check in the files that were updated for a specific fix or for a new change. Just awesome! No more hassle of trying to figure out which files were changed for which task.. especially when you're working on multiple tasks in a huge project. It also tracks the amount of time spent on each task after its activated.. again making it easy for you to provide an estimate or provide better estimates of time spent on each task (for micro-managing bosses). Im yet to play around with the bug tracking feature.. but I already know that Im gonna love that as well.. even if I dont, Im gonna continue using mylyn from now on for creating my personal tasks.. Please give it a try and fall in love with it.
Here's the link that got me onto mylyn:
http://www.ibm.com/developerworks/java/library/j-mylyn1/

Adios.
Arun