1

I have to implement a Tool which reads a config file and runs application/programs specified in the configuration file. A sort of automated runner for tests. I have implemented a program which does that, however I have hit the dependency wall. In my current design Tool parses the config file and retrieves a Map of ProgramType and list of Jobs. Based on ProgramType, a Runner class is chosen and initialized, runner class is a part of Program src.

//this is just a pseudo code
pkg org.Tool

class Tool {
  //after parsing
  runJobs(map) {
    if(map.get() == ProgramType)
      org.Tool.JobStats = org.ProgramType.Runner.run(Job)
  }
}

pkg org.ProgramType

class Runner {
 org.Tool.JobStats run(Job) {
   if(Job = "certain job")
     return CertainJob.run(Job)
 }
}

To build the Tool I need compiled org.ProgramType.*; to build the ProgramType I need org.Tool.Job and org.Tool.JobStats. The "dependency hell" I have created is obviously very bad design. I came with a solution of simply invoking ProgramType jar and storing the JobStats in a jobStats.txt file and once the jar execution finishes, read the file and process it. This solution is not acceptable as Jobs can be run multiple times with many configurations etc, simply to much *.txt files to handle. I think I saw once a compile solution for my problem, something like "partial-compile" Tool, compile ProgramType, recompile Tool. However I can't find it, also it would be wise to get rid of the "dependency hell" anti-pattern. Thus my question "How I should have designed this".

(I hope that the explanation is clear, if not just ask)

SOLVED

As I wrote in the comment @aviad I was looking for a design pattern, to solve my problem. I found one its called "Dependency Inversion Principle". Here I am linking a pdf document describing the pattern, its worth reading (http://www.objectmentor.com/resources/articles/dip.pdf) (Another good explanation http://java.dzone.com/articles/fun-modules). Thank you all for your help (I really liked the frameworks you have recomended).

sinsuren
  • 1,745
  • 2
  • 23
  • 26
alien01
  • 1,334
  • 2
  • 14
  • 31
  • Are you talking about Dependency Injection ? If so, check out Guice here http://code.google.com/p/google-guice/ – tartak Feb 16 '12 at 11:18
  • How I should have designed this? short answer: like maven; even shorter: reflection – guido Feb 16 '12 at 11:21
  • Catalin Thx for the tip I'll look into it. @guido Isn't reflection error prone and hard to maintain? – alien01 Feb 16 '12 at 11:39

1 Answers1

1

I think you still can use most of your code if you can use the SpringBatch framework.

The advantage of using Spring batch is that it is Framework where all the hard job was already done (configuration, multi-threading, persistency etc).

Basically the java programs that you need to run can be executed by running a batch file\shell script that starts:

java -cp %JOB_CLASSPATH% %JOB_MAIN_CLASS_FULLY_QUALIFIED_CLASS_NAME%

So I would use the following design:

The entire solution is Spring -based application. Controller class (your main class) that reads configuration and runs the show. Controller class populates the job queue with jobs and their configurations. Then every job is retrieved from the queue and Spring batch job is instantiated programmatically and run.

You can also use Commons Exec for executing batch files\shell scripts from java.

Later you can move to run in web container (In order to enable configuration changes and jobs triggering over http) - check Spring Batch Admin

You can also run your solution in sceduled manner if you use Quartz FW

Good luck!

aviad
  • 8,229
  • 9
  • 50
  • 98
  • Thx for framework suggestions, I'll also look into them. Though frameworks will solve my problem, I was more wondering (just for the knowledge) how this should be done in J2SE, without the use of external jars. Some sort of "design pattern" for this type of application. – alien01 Feb 17 '12 at 11:03