Sunday, June 6, 2010

Java Hot Deploy Alternative

I have been working with Apache Wicket for the past 9 months or so and I started to tire of the time I was losing. For lack of a better process, I had been making java or html edits and then running "mvn package" at which point I had to sit and wait for a hot deploy on Tomcat. Thats a good 3 or so minutes, and I was tired of losing those 3 minutes.

I discovered something those guys using wicket for some time have known, but I just didn't see the answer until today. With Jetty, you can run an instance with just a few lines of code. With the magic of the Eclipse java debugger, and those few lines of java code, you can start an instance of Jetty and see all of your .java changes in real time. This is NOT hot deploy. No. This is edit java, save java, Eclipse builds automatically, you see the changes.

For this to work, I had to make a few modifications to my Eclipse project. These may or may not be required, its just what worked for me.

* In Project > Properties > Java Build Path : Default output folder = target/MY_APPLICATION/WEB-INF/classes
* In Project > Properties > Java Build Path : Inclusion patterns, I added **/*.html (wicket specific)
* In Run -> Configurations -> Classpath : Added target/MY_APPLICATION/WEB-INF/classes to my classpath
* I use Maven, added pom dependencies:


<properties>
<jetty.version>6.1.4</jetty.version>
</properties>
<!--  JETTY DEPENDENCIES FOR TESTING  -->
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty</artifactId>
<version>${jetty.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-util</artifactId>
<version>${jetty.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-management</artifactId>
<version>${jetty.version}</version>
<scope>provided</scope>
</dependency>



That is it. If you don't use maven, then you will have to get the required jetty jars some other way.

Here is the source:
import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.bio.SocketConnector;
import org.mortbay.jetty.webapp.WebAppContext;
import org.mortbay.jetty.webapp.WebInfConfiguration;
import org.mortbay.jetty.webapp.WebXmlConfiguration;

/**
 * This is a very simple, but very nice way to test out a web app. Using
 * Create a runtime configuration. When I did this, I had to add
 * the maven output folder to the classpath:
 * 
 * target/MY_APPLICATION/WEB-INF/classes
 * 
 * Then, whe you have it running, you can hit enter to kill it.
 * The REAL MAGIC - run the config in DEBUG mode. Any changes to your 
 * java files will be picked up and you can test WITHOUT RESTARTS!!
 * 
 * Of note, in my project properties, I added all the HTML files to the source 
 * location, which has the effect of getting Eclipse to copy over the
 * the HTML files in src/main/java. It doesn't try to compile them, but it does
 * move them to the target/MY_APPLICATION/WEB-INF/classes dir where they 
 * belong.
 * 
 * Now, I don't think this will have any impact at all on Spring configs,
 * but since this starts up SOOOOO much faster than tomcat does, its a 
 * very big win. Even BIGGER - You can see your java changes WITHOUT a restart
 * 
 * @author Russell Simpkins
 */
public class Start {

 public static void main(String[] args) throws Exception {
  Server server = new Server();
  SocketConnector connector = new SocketConnector();
  
  // Set some timeout options to make debugging easier.
  connector.setMaxIdleTime(1000 * 60 * 60);
  connector.setSoLingerTime(-1);
  connector.setPort(8080);
  server.setConnectors(new Connector[] { connector });

  WebAppContext bb = new WebAppContext();
  bb.setServer(server);
  bb.setContextPath("/");
  bb.setWar("target/MY_APPLICATION");
  bb.setConfigurationClasses(new String[] { WebInfConfiguration.class.getName(), WebXmlConfiguration.class.getName() });
        bb.setParentLoaderPriority(true);

  // START JMX SERVER
  // MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
  // MBeanContainer mBeanContainer = new MBeanContainer(mBeanServer);
  // server.getContainer().addEventListener(mBeanContainer);
  // mBeanContainer.start();
  
  server.addHandler(bb);

  try {
   System.out.println(">>> STARTING EMBEDDED JETTY SERVER, PRESS [ENTER] TO STOP");
   server.start();
   System.in.read();
   System.out.println(">>> STOPPING EMBEDDED JETTY SERVER"); 
   server.stop();
   server.join();
  } catch (Exception e) {
   e.printStackTrace();
   System.exit(100);
  }
 }
}

Of Note I found this article helpful http://www.draconianoverlord.com/2009/01/10/war-less-dev-with-jetty.html when digging around.

Wednesday, April 7, 2010

How to get Tramp to stop automatically attempting to connect

I admit it, I tried out Tramp in emacs, and it was cool. However, after you open something in Tramp, it decides that it always wants to connect. Very annoying. It took me a while, but I think I figured out where this was happening, it was because of a recently used list or something in .ido.last

rm -f ~/.ido.last

and emacs will boot without trying to connect. I suppose you could always edit that file or learn more about the ido feature.

Tuesday, April 6, 2010

Making your shell scripts executable under subversion

Here's something I don't do often, but it does happen; you need to mark a shell script as executable in svn so that it comes out of svn as executable:

svn propset svn:executable +x myscript.sh

That's it.

Friday, January 29, 2010

Redirecting output to syslog

I don't know why I never looked into this before, but oh well. If you have a script and you would really like to have the output go to syslog rather than redirecting to a file that will get huge, you can do this:

2>&1 | logger -p daemon.notice -t ${0##*/}[$$]

e.g.

#!/bin/bash
/usr/local/bin/something 2>&1 | logger -p daemon.notice -t ${0##*/}[$$]

This will result in stderr and stdout going to /var/log/messages on standard linux distro like Centos.

Very handy indeed!

Thursday, December 17, 2009

Show all files in finder

I needed to restore some files in /private/etc after deleting them. I know I should have had a backup before the delete, but I didn't. Anyway, to restore with time machine, you need to see the files in finder.

Open terminal and execute:
  • defaults write com.apple.Finder AppleShowAllFiles YES
  • sudo killall Finder
That's it, you can now see your hidden files. To revert:

defaults write com.apple.Finder AppleShowAllFiles NO
sudo killall Finder

Creds goes to these folks.

cups pdf printing on osx

I admit it, I love printing to PDF, and I get more than a little annoyed when it breaks. So, I just went through with some headaches to get cups-pdf working again for me. I had cups-pdf working just fine under 10.5.8 - going to 10.6 is where things changed. At the end of the day, I am fairly certain that I only needed to make sure I had configured my cups to print outside of a user directory e.g.

/opt/local/var/spool/cups-pdf/${USER}

I learned this little tid bit by trying to install cups-pdf from mac ports "sudo port install cups-pdf" the instructions helped a lot!

###########
As of Mac OS X 10.6, cups can no longer write into user

directories, so the output directory for cups-pdf has been
updated to reflect this.  cups-pdf will now write PDF files
into /opt/local/var/spool/cups-pdf/$USER .  You can create a
symlink to this location from Desktop to have it behave as
before:
   ln -s /opt/local/var/spool/cups-pdf/$USER ~/Desktop/cups-pdf

###########

Do this by editing your cups-pdf.conf

sudo vi /etc/cups/cups-pdf.conf

My line is now:

Out /opt/local/var/spool/cups-pdf/${USER}

Then you can make a sym link wherever you like e.g.

ln -s Out /opt/local/var/spool/cups-pdf/russellsimpkins /Users/russellsimpkins/cups-pdf

Of interest to you may be the web interface to your cups system, its located here http://localhost:631/

I had help along the way from http://www.codepoetry.net/projects/cups-pdf-for-mosx and as already mentioned the ports install of cups-pdf.

Wednesday, December 2, 2009

Setting up DAV SVN on Apache

I had to set up another SVN dav for a client today, but I have to admit that I don't do this every day. I use svn for my own stuff, but its been a while since I last set this up. Here are the steps I follow

1. Decide if this location will be a single svn dav or will there be multiple repos. If you host many projects under one dav, then you will get version numbers that are shared and increment with any change. I had this happen to me at Bluefly - its not the end of the world, but it can be a little annoying.

2. Create the folder and then the repo with

svnadmin create /folder/repo

Again, if you were to make your dav had multiple repos, you might just create /folder/repos and then do

svnadmin create /folder/repos/repo-1

3. I'm guessing you aren't going to leave your repo to just anyone, so go ahead and create an htpasswd file to at least secure PUT requests.

htpasswd -bc .svnaccess-file svn-user s3cr3tPwd

4. Modify your apache config. I bet you could do this in an .htaccess file, but I didn't try that yet.


    <Directory "/folder/repo">
       Options Indexes FollowSymLinks
       Order allow,deny
       Allow from all
    </Directory>
    <Location /svn-repo>
     DAV svn
    # This is for a single repo
     SVNPath /folder/repo

     # Limit write permission to list of valid users.
     <Limit GET PUT PROPFIND OPTIONS REPORT>
        AuthType Basic
        AuthBasicProvider file
        AuthUserFile /home/axiomgroup/.svnaccess
        AuthName "Log into the SVN Repo"
        require user svn-user
     </Limit>
    </Location>


That's about it. If you don't secure PUT, then you won't know who made the repo changes. If you remove GET from the Limit option, then your repo will be open to anyone to downlaod from.

If you were to put multiple repos under this one DAV location, then you would want to use SVNParentPath over SVNPath