Tuesday Oct 04, 2011

Tip #11 Subversion Low-Tech Safety Net

Have you ever lost a significant  amount of source code?  If you have you probably already have multiple layers of safety nets.  This stuff is just too hard to do to take a chance on hardware failures, hickups, etc.  

E.g. I remember once I thought I was in my temp directory.  I entered this command:

rm -rf *

Oops.  I was in the root directory!  I.e. stuff indeed happens. 

Today's excruciatingly simple tip:

When you are actively developing code but it is not yet ready to be checked-in.  Yet you have spent a significant chunk of time on it.  I do this:

svn status | sort | tee dome.bat

I edit the dome.bat file and change this:

?       comm-util-3.1.2.save.jar
?       d
?       diffs.txt
?       dome.bat
?       q
A       src\main\java\com\sun\enterprise\universal\process\WindowsCredentials.java
A       src\main\java\com\sun\enterprise\universal\process\WindowsException.java
A       src\main\java\com\sun\enterprise\universal\process\WindowsRemoteAsadmin.java
A       src\main\java\com\sun\enterprise\universal\process\WindowsRemotePinger.java
A       src\main\java\com\sun\enterprise\universal\process\WindowsRemoteScripter.java
A       src\main\java\com\sun\enterprise\util\io\WindowsRemoteFile.java
A       src\main\java\com\sun\enterprise\util\io\WindowsRemoteFileCopyProgress.java
A       src\main\java\com\sun\enterprise\util\io\WindowsRemoteFileSystem.java
M       pom.xml
M       src\main\java\com\sun\enterprise\universal\glassfish\TokenResolver.java

to this:

       jar cvfM comm-util-3.1.2.save.jar src\main\java\com\sun\enterprise\universal\process\WindowsCredentials.java src\main\java\com\sun\enterprise\universal\process\WindowsException.java src\main\java\com\sun\enterprise\universal\process\WindowsRemoteAsadmin.java src\main\java\com\sun\enterprise\universal\process\WindowsRemotePinger.java src\main\java\com\sun\enterprise\universal\process\WindowsRemoteScripter.java src\main\java\com\sun\enterprise\util\io\WindowsRemoteFile.java src\main\java\com\sun\enterprise\util\io\WindowsRemoteFileCopyProgress.java src\main\java\com\sun\enterprise\util\io\WindowsRemoteFileSystem.java pom.xml src\main\java\com\sun\enterprise\universal\glassfish\TokenResolver.java

Now  I simply run the script and email the jar file to my work email account.  My company will be happy to guarantee safety for my jar file. 


Friday Sep 30, 2011

Tip#10 Technique for making your class Immutable

Immutable classes are great.  You never have to worry about concurrency problems.  It also makes the code more readable - if a variable is final you don't have to look around for the other places where it gets modified -- there aren't any. Also the compiler will help you.  If you forget to assign a final variable it's a compile error.  It's also an error to try and reassign it.

Here is a simple trivial technique for setting final variables from a constructor where you need to do processing first.  The point is that you use temp variables to get your final values all lined up.  Then you assign the final values once.

I'll just let the code write the rest of this blog:

public final class DcomInfo {
    private final WindowsCredentials credentials;
    private final Node node;
    private final String password;
    private final String host;
    private final String user;
    private final String windowsDomain;
    private final String remoteNodeRootDirectory;

    public DcomInfo(Node theNode) throws WindowsException {
        node = theNode;

        if (node == null)
            throw new WindowsException(
                    Strings.get("internal.error", "Node is null"));

        if (!isDcomNode(node))
            throw new WindowsException(Strings.get("not.dcom.node",
                    getNode().getName(), getNode().getType()));

        SshConnector conn = node.getSshConnector();
        if (conn == null)
            throw new WindowsException(Strings.get("no.password"));

        SshAuth auth = conn.getSshAuth();
        if (auth == null)
            throw new WindowsException(Strings.get("no.password"));

        String notFinal = auth.getPassword();
        if (!ok(notFinal))
            throw new WindowsException(Strings.get("no.password"));

        password = DcomUtils.resolvePassword(notFinal);

        notFinal = node.getNodeHost();
        if (!ok(notFinal))
            notFinal = conn.getSshHost();
        if (!ok(notFinal))
            throw new WindowsException(Strings.get("no.host"));
        host = resolver.resolve(notFinal);

        notFinal = auth.getUserName();
        if (!ok(notFinal))
            notFinal = System.getProperty("user.name");
        if (!ok(notFinal))
            throw new WindowsException(Strings.get("no.username"));
        user = resolver.resolve(notFinal);

        notFinal = node.getWindowsDomain();
        if (!ok(notFinal))
            notFinal = host;
        windowsDomain = resolver.resolve(notFinal);

        notFinal = node.getInstallDirUnixStyle();
        if (!ok(notFinal))
            throw new WindowsException(Strings.get("no.lib.dir"));

        if (!notFinal.endsWith("/"))
            notFinal += "/";

        notFinal += SystemPropertyConstants.getComponentName();
        remoteInstallRoot = StringUtils.quotePathIfNecessary(notFinal);
        notFinal += "/lib";
        notFinal = StringUtils.quotePathIfNecessary(notFinal);
        notFinal = notFinal.replace('/', '\\');
        nadminParentPath = notFinal;
        nadminPath = notFinal + "\\nadmin.bat";

        String notFinal2 = node.getNodeDirAbsolute();

        if (notFinal2 == null) {
            // no special nodedir -- use the defaults
            notFinal2 = remoteInstallRoot;  // e.g. "d:/glassfish3/glassfish"
            notFinal2 += "/nodes";
        }
        notFinal2 = notFinal2.replace('/', '\\');

        if (!notFinal2.endsWith("\\"))
            notFinal2 += '\\';

        remoteNodeRootDirectory = notFinal2 + node.getName();

        credentials = new WindowsCredentials(getHost(), getWindowsDomain(),
                getUser(), getPassword());
    }

Wednesday Sep 28, 2011

Tip #9 - Advanced Debugger Attach

GlassFish has server-side commands, for instance create-instance, that in-turn call the client side.  It generally does this by calling asadmin's cousin:

glassfish/lib/nadmin[.bat]

with the command. 

But what if you need to debug the spawned client JVM?  Impossible?  No!  Trivial!

Simply do this:

edit nadmin (or nadmin.bat if you are using Windows) and add the java debugging args.

e.g.

-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=1234

 Now simply run the server-side command and then leisurely attach a debugger to port 1234 (make sure you have a breakpoint waiting or you'll miss out). 

If you use NetBeans you can easily debug both server and client at the same time.

Don't forget to undo nadmin when you are done! 


Tuesday Sep 27, 2011

Tip #8 Watch Those RegEx calls -- they are S-L-O-W

I see this construct quite a bit:

String someString ....
someString.replaceAll("\\\\","/");

This is probably a huge waste of time (probably because I didn't time it).  Not only does it do much much much more complex regular expression parsing, for no good reason, it is also much less readable then the "correct" way to do it:

String someString ....
someString.replace('\\','/');


Monday Sep 26, 2011

Tip #7 - Absolute Filenames in Java

I'm busy reading lots and lots of code lately because I need to implant DCOM support.  I just saw this:

  if (nodeDirFile.isAbsolute()) {
                return nodeDir;
            }

Would this surprise you?

File f = new File("/foo/../foo/.././././././foo/././././././../foo/goo");

f.isAbsolute()
will return true.  That is an absolute path as far as Java IO is concerned.  I.e. if it BEGINS with something absolute -- then it is absolute.  Even if it's really really ugly.

What was probably desired is getCanonical().  There is one and only canonical filenames per file.  There are infinite "absolute" filenames per file.


About

ByronNevins

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today