Pages

Between stimulus and response, there is a space. In that space lies our freedom and power to choose our response. In our response lies our growth and our happiness.

Monday, March 29, 2010

Java program into a Windows Service

If you google around, you will see there are a number of ways to do this. I tried the 2 easiest options that worked. In this article, I will talk about option 1 that uses the Apache Commons Daemon project (http://commons.apache.org/daemon/).

You can read up all about the Commons Daemon project in it's homepage. For us the important thing to know is we have to download "procrun". Procrun is actually an umbrella term for a set of libraries and applications. The applications we are concerned with are called "prunsrv" and "prunmgr".

The "prunsrv" application is the Windows Service binary. It is a native windows binary that runs as a windows service and starts up the JVM to run your Java. The "prunmgr" is a GUI application to start/stop and configure the service. It can also be run in the system tray where its icon will show the current state of the service like running or stopped.

Enough talk, lets start!

STEP 1:
Download the binaries (both tomcat6.exe and tomcat6w.exe) from here http://svn.apache.org/repos/asf/tomcat/tc6.0.x/trunk/res/procrun/
tomcat6.exe is prunsrv and tomcat6w.exe is prunmgr. Don’t ask about why they named the two files like that but lets change them after downloading. I am changing them to SomeService.exe and SomeServiceW.exe from tomcat6.exe and tomcat6w.exe respectively. The reason you want to do this is because when you run them the process explorer will list the processes as such

STEP 2:
You need to write a service class like the following. You need to have 3 methods at a minimum and they are main, start and stop. If you have some other methods you want to execute, you can call that to when you start the service. Procrun will run your start method in a thread, and monitor that thread for your method to return.



package com.yourbusiness.function.foo;

/**
* The service class that does the work for you
*/
public class SomeService {

/**
* Flag to know if this service
* instance has been stopped.
*/
private boolean stopped = false;

/**
* Single static instance of the service class
*/
private static SomeService serviceInstance = new SomeService ();

/**
* by default main method is called by prunsrv to start/stop
* the service. Pass the argument "start" to start the service,
* and pass "stop" to stop the service.
*/
public static void main(String args[]) {

String cmd = "start";
if(args.length > 0) {
cmd = args[0];
}

if("start".equals(cmd)) {
serviceInstance.start();
}
else {
serviceInstance.stop();
}
}


/**
* Start this service instance
*/
public void start() {

stopped = false;

System.out.println("SomeService Started " + new java.util.Date());

while(!stopped) {

synchronized(this) {
//do whatever you want to do here
System.out.println("SomeService is working");
}
}

System.out.println("SomeService Stopped " + new java.util.Date());
}

/**
* Stop this service instance
*/
public void stop() {
stopped = true;
synchronized(this) {
this.notify();
}
}

}

STEP 3:
I keep both of the exe files where I run the java class from. So, all of my related files are in one folder. I would execute the following to start my service



C:\SomeService\bin>SomeService.exe //IS//SomeService
--Install=C:\SomeService\bin\SomeService.exe
--Description="SomeService to do something"
--Jvm=auto
--Classpath=C:\SomeService\SomeService.jar
--StartMode=jvm
--StartClass=com.yourbusiness.function.foo.SomeService
--StartMethod=main
--StartParams=start
--StopMode=jvm
--StopClass=com.yourbusiness.function.foo.SomeService
--StopMethod=main
--StopParams=stop
--LogPath=C:\MyService\logs
--StdOutput=auto
--StdError=auto


For all the parameters, you can look at http://commons.apache.org/daemon/procrun.html and configure your service the way you want. I would put this in a bat file and call it addservice.bat

STEP 4:
Once service is added, you have to go to the Services panel and start the process. At that point you can have the service automatically or manually.

Some extra things, if you need.
If you make any mistake during the installation of the service, you can run the following to delete the service
SomeService.exe //DS//SomeService

Tuesday, March 9, 2010

Content and user information from Content DB or Content Services

  1. The metadata for documents is stored in odmv_document.
  2. The contentobject column of odmv_document contains the ID of the associated entry in odmv_contentobject.
  3. The content column in odmv_contentobject contains the ID of the associated entry in either odmm_nonindexedstore or odmm_contentstore
  4. The media column in odmv_contentobject links the contentobject to the odmv_media, where it is indicated in which table/column the document's content is stored.
  5. The full pathname of the document is not stored in any table or view. Each document or directory contains a reference to its parent folder in odmv_folderpathrelationship


QUERY 1:

SELECT FO.name AS "Folder Name", DO.name AS "Document name",
to_date('01-JAN-1970','DD-MON-YYYY')+(DO.createdate/86400000) AS
"Create date",
CO.contentsize, CO.content AS "Content ID", ME.tablename,
ME.columnname
FROM odmv_folderpathrelationship FPR, odmv_folder FO, odmv_document DO,
odmv_contentobject CO, odmv_media ME
WHERE FO.name = 'My Library'
AND FO.id = FPR.leftobject
AND DO.id = FPR.rightobject
AND CO.id = DO.contentobject
AND ME.id = CO.media

The query will list all documents stored in a folder named "My Library", and will display the name of the document, the creation date, the size of the document, as well as the table name, and column name where the document content is stored.


QUERY 2:

Getting information about the owner of a document, you need to join odmv_document.owner with the ID column in odmv_directoryuser, then you can retrieve the name of the owner of the document.

Here is a sample query to find this:

select d.name,u.name from odmv_document d, odmv_directoryuser u where
d.owner=u.id;


QUERY 3:

Getting information about the group of a document, here is a sample query to find this:

select dg.name,du.name from odmv_directorygroup dg,
odmv_groupmemberrelationship gm, odmv_directoryuser du
where dg.name is not null
and dg.id=gm.leftobject
and du.id=gm.rightobject
order by dg.name


QUERY 4:

If you need to know the format of the document (e.g. is it an MS Word, Excel, JPEG, etc), then you would need to join the odmv_document table, with odmv_contentobject, since that is the one holding the format IDs, and then look up the actual format name in odmv_format

Try this example:

SELECT FO.name AS "Folder Name", DO.name AS "Document name", FM.name "Format",
to_date('01-JAN-1970','DD-MON-YYYY')+(DO.createdate/86400000) AS "Create date",
CO.contentsize, CO.content AS "Content ID"
FROM odmv_folderpathrelationship FPR, odmv_folder FO, odmv_document DO, odmv_contentobject CO, odmv_format FM
WHERE FO.name = 'public'
AND FO.id = FPR.leftobject
AND DO.id = FPR.rightobject
AND CO.id = DO.contentobject
AND CO.format = FM.id


QUERY 5:

To list all known libraries

select * from odmv_workspace


QUERY 6:
To determine the total number of documents

select count(*) from odmv_document


QUERY 7:

To determine the amount of space that is used by the Content Services / ContentDB database objects

To calculate this, it is sufficient to look at the sum of space consumed by all tablespaces which are used by content services / contentdb, namely:

CONTENT_IFS_MAIN
CONTENT_IFS_CTX_I
CONTENT_IFS_CTX_K
CONTENT_IFS_CTX_X
CONTENT_IFS_LOB_I
CONTENT_IFS_LOB_M
CONTENT_IFS_LOB_N

To find out how much space is used by these tablespaces, you can run the following SQL:

select tablespace_name,sum(bytes)/1024/1024 as "Size in MB"
from dba_data_files
where tablespace_name in ('CONTENT_IFS_MAIN','CONTENT_IFS_CTX_I',
'CONTENT_IFS_CTX_K','CONTENT_IFS_CTX_X','CONTENT_IFS_LOB_I','CONTENT_IFS_LOB_M',
'CONTENT_IFS_LOB_N')
group by tablespace_name