azkaban-uncached

Added common helper functions for plugins to reduce their dependency. Removing

2/4/2013 9:46:14 PM

Changes

build.properties 4(+2 -2)

Details

build.properties 4(+2 -2)

diff --git a/build.properties b/build.properties
index a6a63c9..1b1ced1 100644
--- a/build.properties
+++ b/build.properties
@@ -1,3 +1,3 @@
 name=azkaban
-version=2.0
-spec.file=azkaban.spec
\ No newline at end of file
+version=2.01
+spec.file=azkaban.spec
diff --git a/src/java/azkaban/execapp/FlowRunnerManager.java b/src/java/azkaban/execapp/FlowRunnerManager.java
index 5060098..dda8674 100644
--- a/src/java/azkaban/execapp/FlowRunnerManager.java
+++ b/src/java/azkaban/execapp/FlowRunnerManager.java
@@ -18,7 +18,6 @@ package azkaban.execapp;
 
 import java.io.File;
 import java.io.IOException;
-import java.lang.reflect.Constructor;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -58,8 +57,6 @@ public class FlowRunnerManager implements EventListener {
 
 	private static final long RECENTLY_FINISHED_TIME_TO_LIVE = 120000; // recently finished secs to clean up. 1 minute
 	
-	private static final String HADOOP_SECURITY_MANAGER_CLASS_PARAM = "hadoop.security.manager.class";
-	
 	private static final int DEFAULT_NUM_EXECUTING_FLOWS = 30;
 	private Map<Pair<Integer,Integer>, ProjectVersion> installedProjects = new ConcurrentHashMap<Pair<Integer,Integer>, ProjectVersion>();
 	private Map<Integer, FlowRunner> runningFlows = new ConcurrentHashMap<Integer, FlowRunner>();
@@ -125,6 +122,7 @@ public class FlowRunnerManager implements EventListener {
 			this.queue = queue;
 		}
 
+		@SuppressWarnings("unused")
 		public void shutdown() {
 			shutdown = true;
 			this.interrupt();
@@ -149,6 +147,7 @@ public class FlowRunnerManager implements EventListener {
 			this.setName("FlowRunnerManager-Cleaner-Thread");
 		}
 		
+		@SuppressWarnings("unused")
 		public void shutdown() {
 			shutdown = true;
 			this.interrupt();
@@ -201,7 +200,7 @@ public class FlowRunnerManager implements EventListener {
 			}
 			
 			for (Map.Entry<Integer, ArrayList<ProjectVersion>> entry: projectVersions.entrySet()) {
-				Integer projectId = entry.getKey();
+				//Integer projectId = entry.getKey();
 				ArrayList<ProjectVersion> installedVersions = entry.getValue();
 				
 				// Keep one version of the project around.
diff --git a/src/java/azkaban/execapp/JobRunner.java b/src/java/azkaban/execapp/JobRunner.java
index 99b41aa..5aa5a04 100644
--- a/src/java/azkaban/execapp/JobRunner.java
+++ b/src/java/azkaban/execapp/JobRunner.java
@@ -23,7 +23,6 @@ import org.apache.log4j.FileAppender;
 import org.apache.log4j.Layout;
 import org.apache.log4j.Logger;
 import org.apache.log4j.PatternLayout;
-import org.apache.log4j.RollingFileAppender;
 
 import azkaban.execapp.event.Event;
 import azkaban.execapp.event.Event.Type;
@@ -35,7 +34,6 @@ import azkaban.executor.ExecutorManagerException;
 import azkaban.jobExecutor.AbstractProcessJob;
 import azkaban.jobExecutor.Job;
 import azkaban.jobtype.JobTypeManager;
-import azkaban.jobtype.JobTypeManagerException;
 
 import azkaban.utils.Props;
 
diff --git a/src/java/azkaban/executor/ExecutableFlow.java b/src/java/azkaban/executor/ExecutableFlow.java
index 277628c..ec05459 100644
--- a/src/java/azkaban/executor/ExecutableFlow.java
+++ b/src/java/azkaban/executor/ExecutableFlow.java
@@ -368,6 +368,7 @@ public class ExecutableFlow {
 	}
 	
 	public void applyUpdateObject(Map<String, Object> updateData) {
+		@SuppressWarnings("unchecked")
 		List<Map<String,Object>> updatedNodes = (List<Map<String,Object>>)updateData.get("nodes");
 		for (Map<String,Object> node: updatedNodes) {
 			String jobId = (String)node.get("jobId");
diff --git a/src/java/azkaban/executor/ExecutorManager.java b/src/java/azkaban/executor/ExecutorManager.java
index d278d59..d9b9685 100644
--- a/src/java/azkaban/executor/ExecutorManager.java
+++ b/src/java/azkaban/executor/ExecutorManager.java
@@ -351,7 +351,7 @@ public class ExecutorManager {
 									if (pair != null) {
 										ExecutionReference ref = pair.getFirst();
 										int numErrors = ref.getNumErrors();
-										if (ref.getNumErrors() < numErrors) {
+										if (ref.getNumErrors() < this.numErrors) {
 											ref.setNextCheckTime(System.currentTimeMillis() + errorThreshold);
 											ref.setNumErrors(++numErrors);
 										}
@@ -615,6 +615,7 @@ public class ExecutorManager {
 			this.port = port;
 		}
 
+		@SuppressWarnings("unused")
 		private ConnectionInfo getOuterType() {
 			return ConnectionInfo.this;
 		}
diff --git a/src/java/azkaban/executor/JdbcExecutorLoader.java b/src/java/azkaban/executor/JdbcExecutorLoader.java
index 1acc59a..e7f7bf1 100644
--- a/src/java/azkaban/executor/JdbcExecutorLoader.java
+++ b/src/java/azkaban/executor/JdbcExecutorLoader.java
@@ -4,12 +4,7 @@ import java.io.BufferedInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
-import java.io.FileNotFoundException;
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-import java.nio.ByteBuffer;
 import java.sql.Connection;
 import java.sql.ResultSet;
 import java.sql.SQLException;
@@ -746,7 +741,7 @@ public class JdbcExecutorLoader implements ExecutorLoader {
 	private static class FetchExecutableFlows implements ResultSetHandler<List<ExecutableFlow>> {
 		private static String FETCH_BASE_EXECUTABLE_FLOW_QUERY = "SELECT exec_id, enc_type, flow_data FROM execution_flows ";
 		private static String FETCH_EXECUTABLE_FLOW = "SELECT exec_id, enc_type, flow_data FROM execution_flows WHERE exec_id=?";
-		private static String FETCH_ACTIVE_EXECUTABLE_FLOW = "SELECT ex.exec_id exec_id, ex.enc_type enc_type, ex.flow_data flow_data FROM execution_flows ex INNER JOIN active_executing_flows ax ON ex.exec_id = ax.exec_id";
+		//private static String FETCH_ACTIVE_EXECUTABLE_FLOW = "SELECT ex.exec_id exec_id, ex.enc_type enc_type, ex.flow_data flow_data FROM execution_flows ex INNER JOIN active_executing_flows ax ON ex.exec_id = ax.exec_id";
 		private static String FETCH_ALL_EXECUTABLE_FLOW_HISTORY = "SELECT exec_id, enc_type, flow_data FROM execution_flows ORDER BY exec_id DESC LIMIT ?, ?";
 		private static String FETCH_EXECUTABLE_FLOW_HISTORY = "SELECT exec_id, enc_type, flow_data FROM execution_flows WHERE project_id=? AND flow_id=? ORDER BY exec_id DESC LIMIT ?, ?";
 		
diff --git a/src/java/azkaban/jobExecutor/AbstractProcessJob.java b/src/java/azkaban/jobExecutor/AbstractProcessJob.java
index 9e18c13..694965d 100644
--- a/src/java/azkaban/jobExecutor/AbstractProcessJob.java
+++ b/src/java/azkaban/jobExecutor/AbstractProcessJob.java
@@ -135,6 +135,7 @@ public abstract class AbstractProcessJob extends AbstractJob {
 			final String content = Streams.asString(reader).trim();
 
 			if (!content.isEmpty()) {
+				@SuppressWarnings("unchecked")
 				Map<String, Object> propMap = (Map<String, Object>)JSONUtils.parseJSONFromString(content);
 
 				for (Map.Entry<String, Object> entry : propMap.entrySet()) {
diff --git a/src/java/azkaban/jobExecutor/ProcessJob.java b/src/java/azkaban/jobExecutor/ProcessJob.java
index 9a0d9ca..4510bbe 100644
--- a/src/java/azkaban/jobExecutor/ProcessJob.java
+++ b/src/java/azkaban/jobExecutor/ProcessJob.java
@@ -27,7 +27,6 @@ import org.apache.log4j.Logger;
 import azkaban.jobExecutor.utils.process.AzkabanProcess;
 import azkaban.jobExecutor.utils.process.AzkabanProcessBuilder;
 import azkaban.utils.Props;
-import azkaban.utils.UndefinedPropertyException;
 
 /*
  * A job that runs a simple unix command
diff --git a/src/java/azkaban/jobExecutor/utils/process/AzkabanProcessBuilder.java b/src/java/azkaban/jobExecutor/utils/process/AzkabanProcessBuilder.java
index 03e225a..f0f2fc1 100644
--- a/src/java/azkaban/jobExecutor/utils/process/AzkabanProcessBuilder.java
+++ b/src/java/azkaban/jobExecutor/utils/process/AzkabanProcessBuilder.java
@@ -30,79 +30,88 @@ import com.google.common.base.Joiner;
  */
 public class AzkabanProcessBuilder {
 
-    private List<String> cmd = new ArrayList<String>();
-    private Map<String, String> env = new HashMap<String, String>();
-    private String workingDir = System.getProperty("user.dir");
-    private Logger logger = Logger.getLogger(AzkabanProcess.class);
-    private int stdErrSnippetSize = 30;
-    private int stdOutSnippetSize = 30;
-    
-    public AzkabanProcessBuilder(String...command) {
-        addArg(command);
-    }
-    
-    public AzkabanProcessBuilder addArg(String...command) {
-        for(String c: command)
-            cmd.add(c);
-        return this;
-    }
-    
-    public AzkabanProcessBuilder setWorkingDir(String dir) {
-        this.workingDir = dir;
-        return this;
-    }
-    
-    public AzkabanProcessBuilder setWorkingDir(File f) {
-        return setWorkingDir(f.getAbsolutePath());
-    }
-    
-    public String getWorkingDir() {
-        return this.workingDir;
-    }
-    
-    public AzkabanProcessBuilder addEnv(String variable, String value) {
-        env.put(variable, value);
-        return this;
-    }
-    
-    public AzkabanProcessBuilder setEnv(Map<String, String> m) {
-        this.env = m;
-        return this;
-    }
-    
-    public Map<String, String> getEnv() {
-        return this.env;
-    }
-    
-    public AzkabanProcessBuilder setStdErrorSnippetSize(int size) {
-        this.stdErrSnippetSize = size;
-        return this;
-    }
-    
-    public AzkabanProcessBuilder setStdOutSnippetSize(int size) {
-        this.stdOutSnippetSize = size;
-        return this;
-    }
-    
-    public AzkabanProcessBuilder setLogger(Logger logger) {
-        this.logger = logger;
-        return this;
-    }
-    
-    public AzkabanProcess build() {
-        return new AzkabanProcess(cmd, env, workingDir, logger);
-    }
-    
-    public List<String> getCommand() {
-        return this.cmd;
-    }
-    
-    public String getCommandString() {
-        return Joiner.on(" ").join(getCommand());
-    }
-    
-    @Override
-    public String toString() {
-        return "ProcessBuilder(cmd = " + Joiner.on(" ").join(cmd) + ", env = " + env + ", cwd = " + workingDir + ")";
-    }
+	private List<String> cmd = new ArrayList<String>();
+	private Map<String, String> env = new HashMap<String, String>();
+	private String workingDir = System.getProperty("user.dir");
+	private Logger logger = Logger.getLogger(AzkabanProcess.class);
+
+	private int stdErrSnippetSize = 30;
+	private int stdOutSnippetSize = 30;
+
+	public AzkabanProcessBuilder(String... command) {
+		addArg(command);
+	}
+
+	public AzkabanProcessBuilder addArg(String... command) {
+		for (String c : command)
+			cmd.add(c);
+		return this;
+	}
+
+	public AzkabanProcessBuilder setWorkingDir(String dir) {
+		this.workingDir = dir;
+		return this;
+	}
+
+	public AzkabanProcessBuilder setWorkingDir(File f) {
+		return setWorkingDir(f.getAbsolutePath());
+	}
+
+	public String getWorkingDir() {
+		return this.workingDir;
+	}
+
+	public AzkabanProcessBuilder addEnv(String variable, String value) {
+		env.put(variable, value);
+		return this;
+	}
+
+	public AzkabanProcessBuilder setEnv(Map<String, String> m) {
+		this.env = m;
+		return this;
+	}
+
+	public Map<String, String> getEnv() {
+		return this.env;
+	}
+
+	public AzkabanProcessBuilder setStdErrorSnippetSize(int size) {
+		this.stdErrSnippetSize = size;
+		return this;
+	}
+
+	public AzkabanProcessBuilder setStdOutSnippetSize(int size) {
+		this.stdOutSnippetSize = size;
+		return this;
+	}
+
+	public int getStdErrorSnippetSize() {
+		return this.stdErrSnippetSize;
+	}
+	
+	public int getStdOutSnippetSize() {
+		return this.stdOutSnippetSize;
+	}
+	
+	public AzkabanProcessBuilder setLogger(Logger logger) {
+		this.logger = logger;
+		return this;
+	}
+
+	public AzkabanProcess build() {
+		return new AzkabanProcess(cmd, env, workingDir, logger);
+	}
+
+	public List<String> getCommand() {
+		return this.cmd;
+	}
+
+	public String getCommandString() {
+		return Joiner.on(" ").join(getCommand());
+	}
+
+	@Override
+	public String toString() {
+		return "ProcessBuilder(cmd = " + Joiner.on(" ").join(cmd) + ", env = " + env + ", cwd = " + workingDir + ")";
+	}
 }
diff --git a/src/java/azkaban/jobtype/JobTypeManagerException.java b/src/java/azkaban/jobtype/JobTypeManagerException.java
index 63dc0dd..987db2f 100644
--- a/src/java/azkaban/jobtype/JobTypeManagerException.java
+++ b/src/java/azkaban/jobtype/JobTypeManagerException.java
@@ -1,8 +1,7 @@
 package azkaban.jobtype;
 
 public class JobTypeManagerException extends RuntimeException {
-
-//	private final static long serialVersionUID = 1;
+	private static final long serialVersionUID = 1L;
 
 	public JobTypeManagerException(String message) {
 		super(message);
diff --git a/src/java/azkaban/project/JdbcProjectLoader.java b/src/java/azkaban/project/JdbcProjectLoader.java
index 028a121..c6b9408 100644
--- a/src/java/azkaban/project/JdbcProjectLoader.java
+++ b/src/java/azkaban/project/JdbcProjectLoader.java
@@ -74,7 +74,6 @@ public class JdbcProjectLoader implements ProjectLoader {
 	
 	private DataSource dataSource;
 	private EncodingType defaultEncodingType = EncodingType.GZIP;
-	private long startTime;
 	
 	public JdbcProjectLoader(Props props) {
 		tempDir = new File(props.getString("project.temp.dir", "temp"));
@@ -295,8 +294,7 @@ public class JdbcProjectLoader implements ProjectLoader {
 			DbUtils.closeQuietly(connection);
 		}
 	}
-	
-	@SuppressWarnings("resource")
+
 	private void uploadProjectFile(Connection connection, Project project, int version, String filetype, String filename, File localFile, String uploader) throws ProjectManagerException {
 		QueryRunner runner = new QueryRunner();
 		long updateTime = System.currentTimeMillis();
@@ -386,7 +384,6 @@ public class JdbcProjectLoader implements ProjectLoader {
 		return handler;
 	}
 	
-	@SuppressWarnings("resource")
 	private ProjectFileHandler getUploadedFile(Connection connection, int projectId, int version) throws ProjectManagerException {
 		QueryRunner runner = new QueryRunner();
 		ProjectVersionResultHandler pfHandler = new ProjectVersionResultHandler();
@@ -957,7 +954,7 @@ public class JdbcProjectLoader implements ProjectLoader {
 			ArrayList<Flow> flows = new ArrayList<Flow>();
 			do {
 				//int projectId = rs.getInt(1);
-				int version = rs.getInt(2);
+				//int version = rs.getInt(2);
 				String flowId = rs.getString(3);
 				//long modifiedTime = rs.getLong(4);
 				int encodingType = rs.getInt(5);
@@ -1093,7 +1090,7 @@ public class JdbcProjectLoader implements ProjectLoader {
 	
 	private static class ProjectVersionResultHandler implements ResultSetHandler<List<ProjectFileHandler>> {
 		private static String SELECT_PROJECT_VERSION = "SELECT project_id, version, upload_time, uploader, file_type, file_name, md5, num_chunks FROM project_versions WHERE project_id=? AND version=?";
-		private static String SELECT_ALL_PER_PROJECT = "SELECT project_id, version, upload_time, uploader, file_type, file_name, md5, num_chunks FROM project_versions WHERE project_id=?";
+		//private static String SELECT_ALL_PER_PROJECT = "SELECT project_id, version, upload_time, uploader, file_type, file_name, md5, num_chunks FROM project_versions WHERE project_id=?";
 		
 		@Override
 		public List<ProjectFileHandler> handle(ResultSet rs) throws SQLException {
diff --git a/src/java/azkaban/scheduler/JdbcScheduleLoader.java b/src/java/azkaban/scheduler/JdbcScheduleLoader.java
index febfd09..caba099 100644
--- a/src/java/azkaban/scheduler/JdbcScheduleLoader.java
+++ b/src/java/azkaban/scheduler/JdbcScheduleLoader.java
@@ -204,7 +204,7 @@ public class JdbcScheduleLoader implements ScheduleLoader {
 	{
 		QueryRunner runner = new QueryRunner();
 		try {
-			int updates = runner.update(connection, UPDATE_NEXT_EXEC_TIME, s.getNextExecTime(), s.getProjectId(), s.getFlowName()); 
+			runner.update(connection, UPDATE_NEXT_EXEC_TIME, s.getNextExecTime(), s.getProjectId(), s.getFlowName()); 
 		} catch (SQLException e) {
 			logger.error(UPDATE_NEXT_EXEC_TIME + " failed.");
 			throw new ScheduleManagerException("Update schedule " + s.getScheduleName() + " into db failed. ", e);
diff --git a/src/java/azkaban/user/Permission.java b/src/java/azkaban/user/Permission.java
index 588855b..7f57290 100644
--- a/src/java/azkaban/user/Permission.java
+++ b/src/java/azkaban/user/Permission.java
@@ -18,7 +18,6 @@ package azkaban.user;
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
 
diff --git a/src/java/azkaban/user/UserManager.java b/src/java/azkaban/user/UserManager.java
index b6f2d1e..114ccbe 100644
--- a/src/java/azkaban/user/UserManager.java
+++ b/src/java/azkaban/user/UserManager.java
@@ -35,7 +35,27 @@ public interface UserManager {
 	 */
 	public User getUser(String username, String password) throws UserManagerException;
 	
+	/**
+	 * Returns true if the user is valid. This is used when adding permissions for users
+	 * 
+	 * @param username
+	 * @return
+	 */
 	public boolean validateUser(String username);
 
+	/**
+	 * Returns true if the group is valid. This is used when adding permissions for groups.
+	 * 
+	 * @param group
+	 * @return
+	 */
+	public boolean validateGroup(String group);
+	
+	/**
+	 * Returns the user role. This may return null.
+	 * 
+	 * @param roleName
+	 * @return
+	 */
 	public Role getRole(String roleName);
 }
diff --git a/src/java/azkaban/user/XmlUserManager.java b/src/java/azkaban/user/XmlUserManager.java
index fdb1a1a..09539b5 100644
--- a/src/java/azkaban/user/XmlUserManager.java
+++ b/src/java/azkaban/user/XmlUserManager.java
@@ -242,4 +242,10 @@ public class XmlUserManager implements UserManager {
 	public Role getRole(String roleName) {
 		return roles.get(roleName);
 	}
+
+	@Override
+	public boolean validateGroup(String group) {
+		// Return true. Validation should be added when groups are added to the xml.
+		return true;
+	}
 }
diff --git a/src/java/azkaban/utils/JSONUtils.java b/src/java/azkaban/utils/JSONUtils.java
index 1207a21..063b129 100644
--- a/src/java/azkaban/utils/JSONUtils.java
+++ b/src/java/azkaban/utils/JSONUtils.java
@@ -6,9 +6,11 @@ import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.Reader;
+import java.io.Writer;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.Map;
 
 import org.codehaus.jackson.JsonFactory;
 import org.codehaus.jackson.JsonNode;
@@ -146,4 +148,100 @@ public class JSONUtils {
 		
 		return (Long)obj;
 	}
+	
+	/*
+	 * Writes json to a stream without using any external dependencies.
+	 * 
+	 * This is useful for plugins or extensions that want to write properties to a writer
+	 * without having to import the jackson, or json libraries. The properties are expected
+	 * to be a map of String keys and String values.
+	 * 
+	 * The other json writing methods are more robust and will handle more cases.
+	 */
+	public static void writePropsNoJarDependency(Map<String, String> properties, Writer writer) throws IOException {
+		writer.write("{\n");
+		int size = properties.size();
+		
+		for (Map.Entry<String, String> entry: properties.entrySet()) {
+			// tab the space
+			writer.write('\t');
+			// Write key
+			writer.write(quoteAndClean(entry.getKey()));
+			writer.write(':');
+			writer.write(quoteAndClean(entry.getValue()));
+			
+			size -= 1;
+			// Add comma only if it's not the last one
+			if (size > 0) {
+				writer.write(',');
+			}
+			writer.write('\n');
+		}
+		writer.write("}");
+	}
+	
+	private static String quoteAndClean(String str) {
+		if (str == null || str.isEmpty()) {
+			return "\"\"";
+		}
+		
+		StringBuffer buffer = new StringBuffer(str.length());
+		buffer.append('"');
+		for (int i = 0; i < str.length(); ++i) {
+			char ch = str.charAt(i);
+			
+			switch(ch) {
+				case '\b':
+					buffer.append("\\b");
+					break;
+				case '\t':
+					buffer.append("\\t");
+					break;
+				case '\n':
+					buffer.append("\\n");
+					break;
+				case '\f':
+					buffer.append("\\f");
+					break;
+				case '\r':
+					buffer.append("\\r");
+					break;
+				case '"':
+				case '\\':
+				case '/':
+					buffer.append('\\');
+					buffer.append(ch);
+					break;
+				default:
+					if (isCharSpecialUnicode(ch)) {
+						buffer.append("\\u");
+						String hexCode = Integer.toHexString(ch);
+						int lengthHexCode = hexCode.length();
+						if (lengthHexCode < 4){
+							buffer.append("0000".substring(0, 4 - lengthHexCode));
+						}
+						buffer.append(hexCode);
+					}
+					else {
+						buffer.append(ch);
+					}
+			}
+		}
+		buffer.append('"');
+		return buffer.toString();
+	}
+	
+	private static boolean isCharSpecialUnicode(char ch) {
+		if (ch < ' ') {
+			return true;
+		}
+		else if ( ch >= '\u0080' && ch < '\u00a0') {
+			return true;
+		}
+		else if ( ch >= '\u2000' && ch < '\u2100') {
+			return true;
+		}
+		
+		return false;
+	}
 }
diff --git a/src/java/azkaban/utils/PropsUtils.java b/src/java/azkaban/utils/PropsUtils.java
index 3c720c4..b81d0e8 100644
--- a/src/java/azkaban/utils/PropsUtils.java
+++ b/src/java/azkaban/utils/PropsUtils.java
@@ -27,10 +27,8 @@ import java.util.UUID;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-//import azkaban.jobExecutor.jobs.dependency.ExecutableFlow;
 import azkaban.executor.ExecutableFlow;
 import org.joda.time.DateTime;
-import org.mortbay.util.ajax.JSON;
 
 public class PropsUtils {
 
diff --git a/src/java/azkaban/utils/StringUtils.java b/src/java/azkaban/utils/StringUtils.java
index eb42770..90fd688 100644
--- a/src/java/azkaban/utils/StringUtils.java
+++ b/src/java/azkaban/utils/StringUtils.java
@@ -15,25 +15,43 @@
  */
 package azkaban.utils;
 
-public class StringUtils
-{
-  public static final char SINGLE_QUOTE = '\'';
-  public static final char DOUBLE_QUOTE = '\"';
-  
-  public static String shellQuote(String s, char quoteCh)
-  {
-    StringBuffer buf = new StringBuffer(s.length()+2);
+import java.util.List;
 
-    buf.append(quoteCh);
-    for (int i = 0; i < s.length(); i++) {
-      final char ch = s.charAt(i);
-      if (ch == quoteCh) {
-        buf.append('\\');
-      }
-      buf.append(ch);
-    }
-    buf.append(quoteCh);
-    
-    return buf.toString();
-  }
+public class StringUtils {
+	public static final char SINGLE_QUOTE = '\'';
+	public static final char DOUBLE_QUOTE = '\"';
+
+	public static String shellQuote(String s, char quoteCh) {
+		StringBuffer buf = new StringBuffer(s.length() + 2);
+
+		buf.append(quoteCh);
+		for (int i = 0; i < s.length(); i++) {
+			final char ch = s.charAt(i);
+			if (ch == quoteCh) {
+				buf.append('\\');
+			}
+			buf.append(ch);
+		}
+		buf.append(quoteCh);
+
+		return buf.toString();
+	}
+	
+	/**
+	 * Use this when you don't want to include Apache Common's string for
+	 * plugins.
+	 * 
+	 * @param list
+	 * @param delimiter
+	 * @return
+	 */
+	public static String join(List<String> list, String delimiter) {
+		StringBuffer buffer = new StringBuffer();
+		for (String str: list) {
+			buffer.append(str);
+			buffer.append(delimiter);
+		}
+		
+		return buffer.toString();
+	}
 }
diff --git a/src/java/azkaban/utils/Triple.java b/src/java/azkaban/utils/Triple.java
index 43a1706..69966ce 100644
--- a/src/java/azkaban/utils/Triple.java
+++ b/src/java/azkaban/utils/Triple.java
@@ -44,6 +44,7 @@ public class Triple<F, S, T> {
 			return false;
 		if (getClass() != obj.getClass())
 			return false;
+		@SuppressWarnings("rawtypes")
 		Triple other = (Triple) obj;
 		if (first == null) {
 			if (other.first != null)
diff --git a/src/java/azkaban/utils/Utils.java b/src/java/azkaban/utils/Utils.java
index 52d2cb2..fb4419f 100644
--- a/src/java/azkaban/utils/Utils.java
+++ b/src/java/azkaban/utils/Utils.java
@@ -27,7 +27,6 @@ import java.io.OutputStream;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
-import java.net.URLClassLoader;
 import java.util.Collection;
 import java.util.Enumeration;
 import java.util.Random;
@@ -37,10 +36,6 @@ import java.util.zip.ZipOutputStream;
 
 import org.apache.commons.io.IOUtils;
 
-import azkaban.execapp.FlowRunner;
-import azkaban.executor.ExecutorManagerException;
-import azkaban.webapp.servlet.admin.InitialSetupServlet;
-
 /**
  * A util helper class full of static methods that are commonly used.
  */
@@ -272,9 +267,9 @@ public class Utils {
 	}
 	
 	public static Object invokeStaticMethod(ClassLoader loader, String className, String methodName, Object ... args) throws ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
-		Class clazz = loader.loadClass(className);
+		Class<?> clazz = loader.loadClass(className);
 		
-		Class[] argTypes = new Class[args.length];
+		Class<?>[] argTypes = new Class[args.length];
 		for (int i=0; i < args.length; ++i) {
 			argTypes[i] = args[i].getClass();
 		}
diff --git a/src/java/azkaban/webapp/AzkabanAdminServer.java b/src/java/azkaban/webapp/AzkabanAdminServer.java
index 47a3dde..3ce503a 100644
--- a/src/java/azkaban/webapp/AzkabanAdminServer.java
+++ b/src/java/azkaban/webapp/AzkabanAdminServer.java
@@ -30,7 +30,7 @@ import azkaban.webapp.session.SessionCache;
 public class AzkabanAdminServer implements AzkabanServer {
 	private static final Logger logger = Logger.getLogger(AzkabanAdminServer.class);
 	private static AzkabanAdminServer app;
-	private static final int NUM_CONNECTIONS = 10;
+	
 	private static final String AZKABAN_DEFAULT_ADMIN_DIR = "admin";
 	private static final String AZKABAN_DEFAULT_ADMIN_PROPERTIES = "admin.properties";
 	private static final String AZKABAN_DEFAULT_WEB_DIR = "web";
@@ -39,6 +39,7 @@ public class AzkabanAdminServer implements AzkabanServer {
 	
 	private static final String USER_MANAGER_CLASS_PARAM = "user.manager.class";
 	private final VelocityEngine velocityEngine;
+	@SuppressWarnings("unused")
 	private final SessionCache sessionCache;
 	private static Server server;
 	private String pluginLibDirectory;
@@ -224,6 +225,7 @@ public class AzkabanAdminServer implements AzkabanServer {
 		return pluginLibDirectory;
 	}
 
+	@SuppressWarnings("unused")
 	private UserManager loadUserManager(Props props) {
 		Class<?> userManagerClass = props.getClass(USER_MANAGER_CLASS_PARAM, null);
 		logger.info("Loading user manager class " + userManagerClass.getName());
diff --git a/src/java/azkaban/webapp/AzkabanWebServer.java b/src/java/azkaban/webapp/AzkabanWebServer.java
index 15022c0..2babb79 100644
--- a/src/java/azkaban/webapp/AzkabanWebServer.java
+++ b/src/java/azkaban/webapp/AzkabanWebServer.java
@@ -20,7 +20,6 @@ import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLClassLoader;
@@ -29,7 +28,6 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
-import java.util.Properties;
 import java.util.TimeZone;
 
 import org.apache.commons.lang.StringUtils;
@@ -63,7 +61,6 @@ import azkaban.webapp.servlet.AzkabanServletContextListener;
 
 import azkaban.webapp.servlet.AbstractAzkabanServlet;
 import azkaban.webapp.servlet.ExecutorServlet;
-import azkaban.webapp.servlet.LoginAbstractAzkabanServlet;
 import azkaban.webapp.servlet.ScheduleServlet;
 import azkaban.webapp.servlet.HistoryServlet;
 import azkaban.webapp.servlet.IndexServlet;
diff --git a/src/java/azkaban/webapp/servlet/AbstractAzkabanServlet.java b/src/java/azkaban/webapp/servlet/AbstractAzkabanServlet.java
index a2820d3..253c7e9 100644
--- a/src/java/azkaban/webapp/servlet/AbstractAzkabanServlet.java
+++ b/src/java/azkaban/webapp/servlet/AbstractAzkabanServlet.java
@@ -17,7 +17,6 @@
 package azkaban.webapp.servlet;
 
 import java.io.IOException;
-import java.net.URL;
 import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.HashMap;
@@ -31,9 +30,6 @@ import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.apache.velocity.Template;
-import org.apache.velocity.app.VelocityEngine;
-import org.codehaus.jackson.map.ObjectMapper;
 import org.joda.time.DateTime;
 import org.joda.time.format.DateTimeFormat;
 import org.joda.time.format.DateTimeFormatter;
@@ -387,8 +383,7 @@ public abstract class AbstractAzkabanServlet extends HttpServlet {
 	 */
 	protected void writeJSON(HttpServletResponse resp, Object obj) throws IOException {
 		resp.setContentType(JSON_MIME_TYPE);
-		ObjectMapper mapper = new ObjectMapper();
-		mapper.writeValue(resp.getOutputStream(), obj);
+		JSONUtils.toJSON(obj, resp.getOutputStream());
 	}
 
 	/**
diff --git a/src/java/azkaban/webapp/servlet/admin/InitialSetupServlet.java b/src/java/azkaban/webapp/servlet/admin/InitialSetupServlet.java
index b4f1b32..744b4f7 100644
--- a/src/java/azkaban/webapp/servlet/admin/InitialSetupServlet.java
+++ b/src/java/azkaban/webapp/servlet/admin/InitialSetupServlet.java
@@ -55,7 +55,6 @@ public class InitialSetupServlet extends AbstractAzkabanServlet {
 	private static final long serialVersionUID = -1;
 	private static final int DEFAULT_UPLOAD_DISK_SPOOL_SIZE = 20 * 1024 * 1024;
 	private static final String DB_DIRECTORY = "db";
-	private static final String LDAP_DIRECTORY = "auth";
 
     private static Logger logger = Logger.getLogger(InitialSetupServlet.class);
 
@@ -207,7 +206,7 @@ public class InitialSetupServlet extends AbstractAzkabanServlet {
 		FileItem item = (FileItem) multipart.get("file");
 		String name = item.getName();
 		
-		final String contentType = item.getContentType();
+		//final String contentType = item.getContentType();
 
 		File tempDir = Utils.createTempDir();
 		OutputStream out = null;
diff --git a/src/java/azkaban/webapp/servlet/ExecutorServlet.java b/src/java/azkaban/webapp/servlet/ExecutorServlet.java
index 4548bf3..a8ddd59 100644
--- a/src/java/azkaban/webapp/servlet/ExecutorServlet.java
+++ b/src/java/azkaban/webapp/servlet/ExecutorServlet.java
@@ -263,9 +263,9 @@ public class ExecutorServlet extends LoginAbstractAzkabanServlet {
 					ajaxFetchJobLogs(req, resp, ret, session.getUser(), exFlow);
 				}
 				else if (ajaxName.equals("flowInfo")) {
-					String projectName = getParam(req, "project");
-					Project project = projectManager.getProject(projectName);
-					String flowName = getParam(req, "flow");
+					//String projectName = getParam(req, "project");
+					//Project project = projectManager.getProject(projectName);
+					//String flowName = getParam(req, "flow");
 					ajaxFetchExecutableFlowInfo(req, resp, ret, session.getUser(), exFlow);
 				}
 			}
@@ -617,7 +617,7 @@ public class ExecutorServlet extends LoginAbstractAzkabanServlet {
 			exflow.setNotifyOnLastFailure(Boolean.parseBoolean(getParam(req, "notifyFailureLast")));
 		}
 		if (hasParam(req, "executingJobOption")) {
-			String option = getParam(req, "jobOption");
+			//String option = getParam(req, "jobOption");
 			// Not set yet
 		}
 		
@@ -644,7 +644,6 @@ public class ExecutorServlet extends LoginAbstractAzkabanServlet {
 	}
 	
 	public class ExecutorVMHelper {
-		@SuppressWarnings("unused")
 		public String getProjectName(int id) {
 			Project project = projectManager.getProject(id);
 			if (project == null) {
diff --git a/src/java/azkaban/webapp/servlet/HistoryServlet.java b/src/java/azkaban/webapp/servlet/HistoryServlet.java
index 9fa9ed3..ac6fed0 100644
--- a/src/java/azkaban/webapp/servlet/HistoryServlet.java
+++ b/src/java/azkaban/webapp/servlet/HistoryServlet.java
@@ -18,7 +18,6 @@
 package azkaban.webapp.servlet;
 
 import java.io.IOException;
-import java.util.ArrayList;
 
 import java.util.HashMap;
 import java.util.List;
@@ -28,7 +27,6 @@ import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.joda.time.DateTime;
 
 import org.joda.time.format.DateTimeFormat;
 
@@ -38,7 +36,6 @@ import azkaban.executor.ExecutorManager;
 import azkaban.executor.ExecutorManagerException;
 import azkaban.project.Project;
 import azkaban.project.ProjectManager;
-import azkaban.utils.JSONUtils;
 import azkaban.webapp.AzkabanWebServer;
 import azkaban.webapp.session.Session;
 
@@ -297,7 +294,6 @@ public class HistoryServlet extends LoginAbstractAzkabanServlet {
 	}
 
 	public class ExecutorVMHelper {
-		@SuppressWarnings("unused")
 		public String getProjectName(int id) {
 			Project project = projectManager.getProject(id);
 			if (project == null) {
diff --git a/src/java/azkaban/webapp/servlet/LoginAbstractAzkabanServlet.java b/src/java/azkaban/webapp/servlet/LoginAbstractAzkabanServlet.java
index c66aff3..a92fb45 100644
--- a/src/java/azkaban/webapp/servlet/LoginAbstractAzkabanServlet.java
+++ b/src/java/azkaban/webapp/servlet/LoginAbstractAzkabanServlet.java
@@ -34,8 +34,6 @@ import org.apache.log4j.Logger;
 import azkaban.user.User;
 import azkaban.user.UserManager;
 import azkaban.user.UserManagerException;
-import azkaban.utils.Props;
-import azkaban.webapp.AzkabanServer;
 import azkaban.webapp.session.Session;
 
 /**
diff --git a/src/java/azkaban/webapp/servlet/ProjectManagerServlet.java b/src/java/azkaban/webapp/servlet/ProjectManagerServlet.java
index 77f48db..4002e4a 100644
--- a/src/java/azkaban/webapp/servlet/ProjectManagerServlet.java
+++ b/src/java/azkaban/webapp/servlet/ProjectManagerServlet.java
@@ -38,7 +38,6 @@ import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
 import org.apache.commons.fileupload.FileItem;
-import org.apache.commons.fileupload.servlet.ServletFileUpload;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.IOUtils;
 import org.apache.log4j.Logger;
@@ -68,7 +67,6 @@ import azkaban.utils.Props;
 import azkaban.utils.Utils;
 import azkaban.webapp.AzkabanWebServer;
 import azkaban.webapp.session.Session;
-import azkaban.webapp.servlet.MultipartParser;
 
 public class ProjectManagerServlet extends LoginAbstractAzkabanServlet {
 	private static final long serialVersionUID = 1;
@@ -575,7 +573,7 @@ public class ProjectManagerServlet extends LoginAbstractAzkabanServlet {
 	
 	private void handleProjectLogsPage(HttpServletRequest req, HttpServletResponse resp, Session session) throws ServletException, IOException {
 		Page page = newPage(req, resp, session, "azkaban/webapp/servlet/velocity/projectlogpage.vm");
-		User user = session.getUser();
+
 		String projectName = getParam(req, "project");
 		
 		Project project = projectManager.getProject(projectName);
@@ -584,7 +582,7 @@ public class ProjectManagerServlet extends LoginAbstractAzkabanServlet {
 		}
 		page.add("projectName", projectName);
 		//page.add("projectManager", projectManager);
-		int bytesSkip = 0;
+		//int bytesSkip = 0;
 		int numBytes = 1024;
 
 		// Really sucks if we do a lot of these because it'll eat up memory fast. But it's expected
diff --git a/src/java/azkaban/webapp/servlet/ScheduleServlet.java b/src/java/azkaban/webapp/servlet/ScheduleServlet.java
index 480ea9a..fd17899 100644
--- a/src/java/azkaban/webapp/servlet/ScheduleServlet.java
+++ b/src/java/azkaban/webapp/servlet/ScheduleServlet.java
@@ -111,7 +111,7 @@ public class ScheduleServlet extends LoginAbstractAzkabanServlet {
 	private void ajaxRemoveSched(HttpServletRequest req, Map<String, Object> ret, User user) throws ServletException{
 		int projectId = getIntParam(req, "projectId");
 		String flowName = getParam(req, "flowName");
-		Pair scheduleId = new Pair(projectId, flowName);
+		Pair<Integer, String> scheduleId = new Pair<Integer, String>(projectId, flowName);
 		Schedule sched = scheduleManager.getSchedule(scheduleId);
 
 //		int projectId = sched.getProjectId();
@@ -197,7 +197,7 @@ public class ScheduleServlet extends LoginAbstractAzkabanServlet {
 		    hour += 12;
 		hour %= 24;
 
-		String submitUser = user.getUserId();
+//		String submitUser = user.getUserId();
 //		String userExec = userSubmit;//getParam(req, "userExec");
 //		String scheduleId = projectId + "." + flowName;
 		DateTime submitTime = new DateTime();
diff --git a/src/java/azkaban/webapp/servlet/velocity/executingflowpage.vm b/src/java/azkaban/webapp/servlet/velocity/executingflowpage.vm
index 670b67b..3a2e851 100644
--- a/src/java/azkaban/webapp/servlet/velocity/executingflowpage.vm
+++ b/src/java/azkaban/webapp/servlet/velocity/executingflowpage.vm
@@ -139,89 +139,8 @@
 						<tr><td class="first">Duration</td><td id="duration">-</td></tr>
 					</table>
 				</div>
-						
-	            <div id="modalBackground" class="modalBackground2">
-	                <div id="executing-options" class="modal modalContainer2">
-	                	<a href='#' title='Close' class='modal-close'>x</a>
-	                		<h3>Executing Flow Options</h3>
-	                		<div>
-	                			<ul class="optionsPicker">
-	                				<li id="generalOptions">General Options</li>
-	                				<li id="flowOptions">Flow Options</li>
-	                			</ul>
-	                		</div>
-	                		<div class="optionsPane">
-	                			<div id="generalPanel" class="generalPanel panel">
-	                				<div id="completeActions">
-	                					<h4>Completion Actions</h4>
-		                				<dl>
-		                					<dt>Failure Action</dt>
-		                					<dd>
-		                						<select id="failureAction" name="failureAction">
-		                							<option value="finishCurrent">Finish Current Running</option>
-		                							<option value="cancelImmediately">Cancel All</option>
-		                							<option value="finishPossible">Finish All Possible</option>
-		                						</select>
-											</dd>
-		                					<dt>Failure Email</dt>
-		                					<dd>
-		                						<textarea id="failureEmails"></textarea>
-		                					</dd>
-		                					<dt>Notify on Failure</dt>
-		                					<dd>
-		                						<input id="notifyFailureFirst" class="checkbox" type="checkbox" name="notify" value="first" checked >First Failure</input>
-		                						<input id="notifyFailureLast" class="checkbox" type="checkbox" name="notify" value="last">Flow Stop</input>
-		                					</dd>
-		                					<dt>Success Email</dt>
-		                					<dd>
-		                						<textarea id="successEmails"></textarea>
-		                					</dd>
-		                					<dt>Concurrent Execution</dt>
-		                					<dd id="executingJob" class="disabled">
-		                						<input id="ignore" class="radio" type="radio" name="concurrent" value="ignore" checked /><label class="radioLabel" for="ignore">Run Concurrently</label>
-		                						<input id="pipeline" class="radio" type="radio" name="concurrent" value="pipeline" /><label class="radioLabel" for="pipeline">Pipeline</label>
-		                						<input id="queue" class="radio" type="radio" name="concurrent" value="queue" /><label class="radioLabel" for="queue">Queue Job</label>
-		                					</dd>
-		                				</dl>
-	                				</div>
-	                				<div id="flowPropertyOverride">
-	                					<h4>Flow Property Override</h4>
-	                					<div class="tableDiv">
-		                					<table>
-		                						<thead>
-		                							<tr>
-			                							<th>Name</th>
-			                							<th>Value</th>
-			                						</tr>
-		                						</thead>
-		                						<tbody>
-		                							<tr id="addRow"><td id="addRow-col" colspan="2"><span class="addIcon"></span><a href="#">Add Row</a></td></tr>
-		                						</tbody>
-		                					</table>
-	                					</div>
-	                				</div>
-	                			</div>
-								<div id="graphPanel" class="graphPanel panel">
-									<div id="jobListCustom" class="jobList">
-										<div class="filterList">
-											<input class="filter" placeholder="  Job Filter" />
-										</div>
-										<div class="list">
-										</div>
-										<div class="btn5 resetPanZoomBtn" >Reset Pan Zoom</div>
-									</div>
-								    <div id="svgDivCustom" class="svgDiv" >
-								    	<svg class="svgGraph" xmlns="http://www.w3.org/2000/svg" version="1.1" shape-rendering="optimize-speed" text-rendering="optimize-speed" >
-										</svg>
-									</div>
-		                        </div>
-	                        </div>
-                    		<div class="actions">
-	                                <a class="yes btn1" id="execute-btn" href="#">Execute Now</a>
-	                                <a class="no simplemodal-close btn3" id="cancel-btn" href="#">Cancel</a>
-	                        </div>
-	                </div>
-                </div>
+
+#parse( "azkaban/webapp/servlet/velocity/executionoptionspanel.vm" )
 #end
 		<ul id="jobMenu" class="contextMenu">  
 			<li class="open"><a href="#open">Open...</a></li>
diff --git a/src/java/azkaban/webapp/servlet/velocity/executionoptionspanel.vm b/src/java/azkaban/webapp/servlet/velocity/executionoptionspanel.vm
new file mode 100644
index 0000000..a16ddd7
--- /dev/null
+++ b/src/java/azkaban/webapp/servlet/velocity/executionoptionspanel.vm
@@ -0,0 +1,82 @@
+	<div id="modalBackground" class="modalBackground2">
+	<div id="executing-options" class="modal modalContainer2">
+		<a href='#' title='Close' class='modal-close'>x</a>
+			<h3>Executing Flow Options</h3>
+			<div>
+				<ul class="optionsPicker">
+					<li id="generalOptions">General Options</li>
+					<li id="flowOptions">Flow Options</li>
+				</ul>
+			</div>
+			<div class="optionsPane">
+				<div id="generalPanel" class="generalPanel panel">
+					<div id="completeActions">
+						<h4>Completion Actions</h4>
+						<dl>
+							<dt>Failure Action</dt>
+							<dd>
+								<select id="failureAction" name="failureAction">
+									<option value="finishCurrent">Finish Current Running</option>
+									<option value="cancelImmediately">Cancel All</option>
+									<option value="finishPossible">Finish All Possible</option>
+								</select>
+											</dd>
+							<dt>Failure Email</dt>
+							<dd>
+								<textarea id="failureEmails"></textarea>
+							</dd>
+							<dt>Notify on Failure</dt>
+							<dd>
+								<input id="notifyFailureFirst" class="checkbox" type="checkbox" name="notify" value="first" checked >First Failure</input>
+								<input id="notifyFailureLast" class="checkbox" type="checkbox" name="notify" value="last">Flow Stop</input>
+							</dd>
+							<dt>Success Email</dt>
+							<dd>
+								<textarea id="successEmails"></textarea>
+							</dd>
+							<dt>Concurrent Execution</dt>
+							<dd id="executingJob" class="disabled">
+								<input id="ignore" class="radio" type="radio" name="concurrent" value="ignore" checked /><label class="radioLabel" for="ignore">Run Concurrently</label>
+								<input id="pipeline" class="radio" type="radio" name="concurrent" value="pipeline" /><label class="radioLabel" for="pipeline">Pipeline</label>
+								<input id="queue" class="radio" type="radio" name="concurrent" value="queue" /><label class="radioLabel" for="queue">Queue Job</label>
+							</dd>
+						</dl>
+					</div>
+					<div id="flowPropertyOverride">
+						<h4>Flow Property Override</h4>
+						<div class="tableDiv">
+							<table>
+								<thead>
+									<tr>
+										<th>Name</th>
+										<th>Value</th>
+									</tr>
+								</thead>
+								<tbody>
+									<tr id="addRow"><td id="addRow-col" colspan="2"><span class="addIcon"></span><a href="#">Add Row</a></td></tr>
+								</tbody>
+							</table>
+						</div>
+					</div>
+				</div>
+								<div id="graphPanel" class="graphPanel panel">
+									<div id="jobListCustom" class="jobList">
+										<div class="filterList">
+											<input class="filter" placeholder="  Job Filter" />
+										</div>
+										<div class="list">
+										</div>
+										<div class="btn5 resetPanZoomBtn" >Reset Pan Zoom</div>
+									</div>
+								<div id="svgDivCustom" class="svgDiv" >
+									<svg class="svgGraph" xmlns="http://www.w3.org/2000/svg" version="1.1" shape-rendering="optimize-speed" text-rendering="optimize-speed" >
+										</svg>
+									</div>
+		</div>
+	</div>
+		<div class="actions">
+	<a class="yes btn1" id="execute-btn" href="#">Execute Now</a>
+	<a class="no simplemodal-close btn3" id="cancel-btn" href="#">Cancel</a>
+	</div>
+	</div>
+</div>
\ No newline at end of file
diff --git a/src/java/azkaban/webapp/servlet/velocity/flowpage.vm b/src/java/azkaban/webapp/servlet/velocity/flowpage.vm
index ee2436b..e28dab6 100644
--- a/src/java/azkaban/webapp/servlet/velocity/flowpage.vm
+++ b/src/java/azkaban/webapp/servlet/velocity/flowpage.vm
@@ -18,7 +18,7 @@
 <html>
 	<head>
 #parse( "azkaban/webapp/servlet/velocity/style.vm" )
-		<script type="text/javascript" src="${context}/js/jquery/jquery.js"></script>    
+		<script type="text/javascript" src="${context}/js/jquery/jquery.js"></script>	
 		<script type="text/javascript" src="${context}/js/jqueryui/jquery-ui.custom.min.js"></script>
 		<script type="text/javascript" src="${context}/js/jqueryui/jquery.ui.datepicker.min.js"></script>
 		<script type="text/javascript" src="${context}/js/azkaban.date.utils.js"></script>  
@@ -131,145 +131,63 @@
 					</div>
 				</div>
 		<!-- modal content -->
-                <div id="schedule-flow" class="modal">
-                        <h3>Schedule Flow</h3>
-                        <div id="errorMsg" class="box-error-message">$errorMsg</div>
+				<div id="schedule-flow" class="modal">
+						<h3>Schedule Flow</h3>
+						<div id="errorMsg" class="box-error-message">$errorMsg</div>
 
 						<div class="box">
-                                        <form id="sched-form" method="post" action="${context}/">
-                                                <div class="sched-form">
-                                                	<dl>
-                                                		<dt>Schedule Time</dt>
-                                            			<dd>
-                                            				<input id="hour" type="text" size="2" value="12"/>
-                                            				<input id="minutes" type="text" size="2" value="00"/>
+										<form id="sched-form" method="post" action="${context}/">
+												<div class="sched-form">
+													<dl>
+														<dt>Schedule Time</dt>
+														<dd>
+															<input id="hour" type="text" size="2" value="12"/>
+															<input id="minutes" type="text" size="2" value="00"/>
 															<select id="am_pm">
-		                                                      <option>pm</option>
-		                                                      <option>am</option>
-		                                                    </select>
-		                                                    <select id="timezone">
-		                                                      <option>PDT</option>
-		                                                      <option>UTC</option>
-		                                                    </select>
-                                            			</dd>
-                                                		<dt>Schedule Date</dt><dd><input type="text" id="datepicker" /></dd>
-                                                		<dt>Recurrence</dt>
-                                                		<dd>
-                                                			<input id="is_recurring" type="checkbox" checked  />
-                                                			<span>repeat every</span>
-                                            			 	<input id="period" type="text" size="2" value="1"/>
-		                                                    <select id="period_units">
-		                                                      <option value="d">Days</option>
-		                                                      <option value="h">Hours</option>
-		                                                      <option value="m">Minutes</option>
-		                                                      <option value="M">Months</option>
-		                                                      <option value="w">Weeks</option>
-		                                                    </select>
-                                                		</dd>
-                                                	</dl>
+															  <option>pm</option>
+															  <option>am</option>
+															</select>
+															<select id="timezone">
+															  <option>PDT</option>
+															  <option>UTC</option>
+															</select>
+														</dd>
+														<dt>Schedule Date</dt><dd><input type="text" id="datepicker" /></dd>
+														<dt>Recurrence</dt>
+														<dd>
+															<input id="is_recurring" type="checkbox" checked  />
+															<span>repeat every</span>
+														 	<input id="period" type="text" size="2" value="1"/>
+															<select id="period_units">
+															  <option value="d">Days</option>
+															  <option value="h">Hours</option>
+															  <option value="m">Minutes</option>
+															  <option value="M">Months</option>
+															  <option value="w">Weeks</option>
+															</select>
+														</dd>
+													</dl>
 
-                                                </div>
+												</div>
 
-                                        </form>
-                        </div>
-                                
+										</form>
+						</div>
+								
 
-                        <div class="actions">
-                                <a class="yes btn2" id="schedule-btn" href="#">Schedule The Flow</a>
-                                <a class="no simplemodal-close btn3" href="#">Cancel</a>
-                        </div>
-                </div>
-                <div id="invalid-session" class="modal">
-                        <h3>Invalid Session</h3>
-                        <p>Session has expired. Please re-login.</p>
-                        <div class="actions">
-                                <a class="yes btn3" id="login-btn" href="#">Re-login</a>
-                        </div>
-                </div>
-                
-                <div id="modalBackground" class="modalBackground2">
-	                <div id="executing-options" class="modal modalContainer2">
-	                	<a href='#' title='Close' class='modal-close'>x</a>
-	                		<h3>Executing Flow Options</h3>
-	                		<div>
-	                			<ul class="optionsPicker">
-	                				<li id="generalOptions">General Options</li>
-	                				<li id="flowOptions">Flow Options</li>
-	                			</ul>
-	                		</div>
-	                		<div class="optionsPane">
-	                			<div id="generalPanel" class="generalPanel panel">
-	                				<div id="completeActions">
-	                					<h4>Completion Actions</h4>
-		                				<dl>
-		                					<dt class="disabled">Failure Action</dt>
-		                					<dd>
-		                						<select id="failureAction" name="failureAction">
-		                							<option value="finishCurrent">Finish Current Running</option>
-		                							<option value="cancelImmediately">Cancel All</option>
-		                							<option value="finishPossible">Finish All Possible</option>
-		                						</select>
-											</dd>
-		                					<dt>Failure Email</dt>
-		                					<dd>
-		                						<textarea id="failureEmails"></textarea>
-		                					</dd>
-		                					<dt>Notify on Failure</dt>
-		                					<dd>
-		                						<input id="notifyFailureFirst" class="checkbox" type="checkbox" name="notify" value="first" checked >First Failure</input>
-		                						<input id="notifyFailureLast" class="checkbox" type="checkbox" name="notify" value="last">Flow Stop</input>
-		                					</dd>
-		                					<dt>Success Email</dt>
-		                					<dd>
-		                						<textarea id="successEmails"></textarea>
-		                					</dd>
-		                					<dt class="disabled" >Concurrent Execution</dt>
-		                					<dd id="executingJob" class="disabled">
-		                						<input id="ignore" class="radio" type="radio" name="concurrent" value="ignore" checked /><label class="radioLabel" for="ignore">Run Concurrently</label>
-		                						<input id="pipeline" class="radio" type="radio" name="concurrent" value="pipeline" /><label class="radioLabel" for="pipeline">Pipeline</label>
-		                						<input id="queue" class="radio" type="radio" name="concurrent" value="queue" /><label class="radioLabel" for="queue">Queue Job</label>
-		                					</dd>
-		                				</dl>
-	                				</div>
-	                				<div id="flowPropertyOverride">
-	                					<h4>Flow Property Override</h4>
-	                					<div class="tableDiv">
-		                					<table>
-		                						<thead>
-		                							<tr>
-			                							<th>Name</th>
-			                							<th>Value</th>
-			                						</tr>
-		                						</thead>
-		                						<tbody>
-		                							<tr id="addRow"><td id="addRow-col" colspan="2"><span class="addIcon"></span><a href="#">Add Row</a></td></tr>
-		                						</tbody>
-		                					</table>
-	                					</div>
-	                				</div>
-	                			</div>
-								<div id="graphPanel" class="graphPanel panel">
-									<div id="jobListCustom" class="jobList">
-										<div class="filterList">
-											<input class="filter" placeholder="  Job Filter" />
-										</div>
-										<div class="list">
-										</div>
-										<div class="btn5 resetPanZoomBtn" >Reset Pan Zoom</div>
-									</div>
-								    <div id="svgDivCustom" class="svgDiv" >
-								    	<svg class="svgGraph" xmlns="http://www.w3.org/2000/svg" version="1.1" shape-rendering="optimize-speed" text-rendering="optimize-speed" >
-										</svg>
-									</div>
-		                        </div>
-	                        </div>
-                    		<div class="actions">
-	                                <a class="yes btn1" id="execute-btn" href="#">Execute Now</a>
-	                                <a class="no simplemodal-close btn3" id="cancel-btn" href="#">Cancel</a>
-	                        </div>
-	                </div>
-                </div>
-                
+						<div class="actions">
+								<a class="yes btn2" id="schedule-btn" href="#">Schedule The Flow</a>
+								<a class="no simplemodal-close btn3" href="#">Cancel</a>
+						</div>
+				</div>
+				<div id="invalid-session" class="modal">
+						<h3>Invalid Session</h3>
+						<p>Session has expired. Please re-login.</p>
+						<div class="actions">
+								<a class="yes btn3" id="login-btn" href="#">Re-login</a>
+						</div>
+				</div>
+				
+#parse( "azkaban/webapp/servlet/velocity/executionoptionspanel.vm" )
 #end
 		<ul id="jobMenu" class="contextMenu">  
 			<li class="open"><a href="#open">Open...</a></li>
diff --git a/unit/java/azkaban/scheduler/JdbcScheduleLoaderTest.java b/unit/java/azkaban/scheduler/JdbcScheduleLoaderTest.java
index 84dd074..f888f45 100644
--- a/unit/java/azkaban/scheduler/JdbcScheduleLoaderTest.java
+++ b/unit/java/azkaban/scheduler/JdbcScheduleLoaderTest.java
@@ -4,8 +4,6 @@ import java.sql.Connection;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
 
 import javax.sql.DataSource;
@@ -50,7 +48,7 @@ public class JdbcScheduleLoaderTest {
 		CountHandler countHandler = new CountHandler();
 		QueryRunner runner = new QueryRunner();
 		try {
-			int count = runner.query(connection, "SELECT COUNT(1) FROM schedules", countHandler);
+			runner.query(connection, "SELECT COUNT(1) FROM schedules", countHandler);
 		} catch (SQLException e) {
 			e.printStackTrace();
 			testDBExists = false;
@@ -82,8 +80,7 @@ public class JdbcScheduleLoaderTest {
 //		CountHandler countHandler = new CountHandler();
 		QueryRunner runner = new QueryRunner();
 		try {
-			int count = runner.update(connection, "DELETE FROM schedules");
-			
+			runner.update(connection, "DELETE FROM schedules");
 		} catch (SQLException e) {
 			e.printStackTrace();
 			testDBExists = false;
diff --git a/unit/java/azkaban/test/execapp/FlowRunnerTest.java b/unit/java/azkaban/test/execapp/FlowRunnerTest.java
index e4496bb..feaec68 100644
--- a/unit/java/azkaban/test/execapp/FlowRunnerTest.java
+++ b/unit/java/azkaban/test/execapp/FlowRunnerTest.java
@@ -7,7 +7,6 @@ import java.util.HashMap;
 import junit.framework.Assert;
 
 import org.apache.commons.io.FileUtils;
-import org.apache.log4j.Logger;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -24,11 +23,9 @@ import azkaban.flow.Flow;
 import azkaban.jobtype.JobTypeManager;
 import azkaban.test.executor.JavaJob;
 import azkaban.utils.JSONUtils;
-import azkaban.utils.Props;
 
 public class FlowRunnerTest {
 	private File workingDir;
-	private Logger logger = Logger.getLogger(FlowRunnerTest.class);
 	private JobTypeManager jobtypeManager;
 	public FlowRunnerTest() {
 		
@@ -348,8 +345,8 @@ public class FlowRunnerTest {
 	}
 	
 	private FlowRunner createFlowRunner(ExecutableFlow flow, ExecutorLoader loader, EventCollectorListener eventCollector) throws Exception {
-		File testDir = new File("unit/executions/exectest1");
-		MockProjectLoader projectLoader = new MockProjectLoader(new File(flow.getExecutionPath()));
+		//File testDir = new File("unit/executions/exectest1");
+		//MockProjectLoader projectLoader = new MockProjectLoader(new File(flow.getExecutionPath()));
 		
 		loader.uploadExecutableFlow(flow);
 		FlowRunner runner = new FlowRunner(flow, loader, jobtypeManager);
@@ -361,7 +358,7 @@ public class FlowRunnerTest {
 	private FlowRunner createFlowRunner(ExecutorLoader loader, EventCollectorListener eventCollector, String flowName) throws Exception {
 		File testDir = new File("unit/executions/exectest1");
 		ExecutableFlow exFlow = prepareExecDir(testDir, flowName, 1);
-		MockProjectLoader projectLoader = new MockProjectLoader(new File(exFlow.getExecutionPath()));
+		//MockProjectLoader projectLoader = new MockProjectLoader(new File(exFlow.getExecutionPath()));
 		
 		loader.uploadExecutableFlow(exFlow);
 		FlowRunner runner = new FlowRunner(exFlow, loader, jobtypeManager);
diff --git a/unit/java/azkaban/test/execapp/JobRunnerTest.java b/unit/java/azkaban/test/execapp/JobRunnerTest.java
index a14251b..c11b934 100644
--- a/unit/java/azkaban/test/execapp/JobRunnerTest.java
+++ b/unit/java/azkaban/test/execapp/JobRunnerTest.java
@@ -2,7 +2,6 @@ package azkaban.test.execapp;
 
 import java.io.File;
 import java.io.IOException;
-import java.util.StringTokenizer;
 
 import junit.framework.Assert;
 
@@ -266,21 +265,5 @@ public class JobRunnerTest {
 		runner.addListener(listener);
 		return runner;
 	}
-	
-	private static String getSourcePathFromClass(Class containedClass) {
-		File file = new File(containedClass.getProtectionDomain().getCodeSource().getLocation().getPath());
 
-		if (!file.isDirectory() && file.getName().endsWith(".class")) {
-			String name = containedClass.getName();
-			StringTokenizer tokenizer = new StringTokenizer(name, ".");
-			while(tokenizer.hasMoreTokens()) {
-				tokenizer.nextElement();
-				file = file.getParentFile();
-			}
-			return file.getPath();  
-		}
-		else {
-			return containedClass.getProtectionDomain().getCodeSource().getLocation().getPath();
-		}
-	}
 }
\ No newline at end of file
diff --git a/unit/java/azkaban/test/execapp/MockExecutorLoader.java b/unit/java/azkaban/test/execapp/MockExecutorLoader.java
index 1e5fc79..8030d93 100644
--- a/unit/java/azkaban/test/execapp/MockExecutorLoader.java
+++ b/unit/java/azkaban/test/execapp/MockExecutorLoader.java
@@ -2,7 +2,6 @@ package azkaban.test.execapp;
 
 import java.io.File;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 
@@ -65,6 +64,7 @@ public class MockExecutorLoader implements ExecutorLoader {
 
 	}
 
+	@SuppressWarnings("unchecked")
 	@Override
 	public void updateExecutableFlow(ExecutableFlow flow) throws ExecutorManagerException {
 		ExecutableFlow toUpdate = flows.get(flow.getExecutionId());
diff --git a/unit/java/azkaban/test/executor/JavaJob.java b/unit/java/azkaban/test/executor/JavaJob.java
index d5cf9ca..22166cd 100644
--- a/unit/java/azkaban/test/executor/JavaJob.java
+++ b/unit/java/azkaban/test/executor/JavaJob.java
@@ -70,7 +70,7 @@ public class JavaJob extends JavaProcessJob {
 		return classPath;
 	}
 
-	private static String getSourcePathFromClass(Class containedClass) {
+	private static String getSourcePathFromClass(Class<?> containedClass) {
 		File file = new File(containedClass.getProtectionDomain().getCodeSource().getLocation().getPath());
 
 		if (!file.isDirectory() && file.getName().endsWith(".class")) {
diff --git a/unit/java/azkaban/test/executor/JavaJobRunnerMain.java b/unit/java/azkaban/test/executor/JavaJobRunnerMain.java
index 8085ab3..9add12a 100644
--- a/unit/java/azkaban/test/executor/JavaJobRunnerMain.java
+++ b/unit/java/azkaban/test/executor/JavaJobRunnerMain.java
@@ -17,7 +17,6 @@ package azkaban.test.executor;
  */
 
 import azkaban.jobExecutor.ProcessJob;
-import azkaban.utils.JSONUtils;
 import azkaban.utils.Props;
 
 import org.apache.log4j.ConsoleAppender;
@@ -34,12 +33,10 @@ import java.io.OutputStream;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
-import java.security.PrivilegedExceptionAction;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Properties;
-import azkaban.test.executor.SleepJavaJob;
 
 public class JavaJobRunnerMain {
 
@@ -264,8 +261,7 @@ public class JavaJobRunnerMain {
 			Constructor<?> con = getConstructor(runningClass, String.class, Map.class);
 			logger.info("Constructor found " + con.toGenericString());
 
-			@SuppressWarnings("rawtypes")
-			HashMap map = new HashMap();
+			HashMap<Object, Object> map = new HashMap<Object, Object>();
 			for (Map.Entry<Object, Object> entry : properties.entrySet()) {
 				map.put(entry.getKey(), entry.getValue());
 			}
diff --git a/unit/java/azkaban/test/executor/SleepJavaJob.java b/unit/java/azkaban/test/executor/SleepJavaJob.java
index 6c0fa4d..29b0bb8 100644
--- a/unit/java/azkaban/test/executor/SleepJavaJob.java
+++ b/unit/java/azkaban/test/executor/SleepJavaJob.java
@@ -5,7 +5,7 @@ import java.util.Map;
 public class SleepJavaJob {
 	private boolean fail;
 	private String seconds;
-	@SuppressWarnings("unchecked")
+
 	public SleepJavaJob(String id, Map<String, String> parameters) {
 		String failStr = parameters.get("fail");
 		if (failStr == null || failStr.equals("false")) {
diff --git a/unit/java/azkaban/test/utils/JsonUtilsTest.java b/unit/java/azkaban/test/utils/JsonUtilsTest.java
new file mode 100644
index 0000000..87c81e9
--- /dev/null
+++ b/unit/java/azkaban/test/utils/JsonUtilsTest.java
@@ -0,0 +1,58 @@
+package azkaban.test.utils;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+import azkaban.utils.JSONUtils;
+
+public class JsonUtilsTest {
+	@Test
+	public void writePropsNoJarDependencyTest1() throws IOException {
+		Map<String, String> test = new HashMap<String,String>();
+		test.put("\"myTest\n\b", "myValue\t\\");
+		test.put("normalKey", "Other key");
+		
+		StringWriter writer = new StringWriter();
+		JSONUtils.writePropsNoJarDependency(test, writer);
+		
+		String jsonStr = writer.toString();
+		System.out.println(writer.toString());
+		
+		@SuppressWarnings("unchecked")
+		Map<String,String> result = (Map<String,String>)JSONUtils.parseJSONFromString(jsonStr);
+		checkInAndOut(test, result);
+	}
+	
+	@Test
+	public void writePropsNoJarDependencyTest2() throws IOException {
+		Map<String, String> test = new HashMap<String,String>();
+		test.put("\"myTest\n\b", "myValue\t\\");
+		
+		StringWriter writer = new StringWriter();
+		JSONUtils.writePropsNoJarDependency(test, writer);
+		
+		String jsonStr = writer.toString();
+		System.out.println(writer.toString());
+		
+		@SuppressWarnings("unchecked")
+		Map<String,String> result = (Map<String,String>)JSONUtils.parseJSONFromString(jsonStr);
+		checkInAndOut(test, result);
+	}
+	
+	private static void checkInAndOut(Map<String, String> before, Map<String, String> after) {
+		for (Map.Entry<String, String> entry: before.entrySet()) {
+			String key = entry.getKey();
+			String value = entry.getValue();
+			
+			String retValue = after.get(key);
+			Assert.assertEquals(value, retValue);
+		}
+	}
+	
+}
\ No newline at end of file