Random JMX stuff

var urlString = "service:jmx:rmi://127.0.0.1/jndi/rmi://127.0.0.1:6996/jmxrmi";
var ManagementFactory = createObject("java","java.lang.management.ManagementFactory");
var MBeanServerConnection = createObject("java","javax.management.MBeanServerConnection");
var ObjectInstance = createObject("java","javax.management.ObjectInstance");
var ObjectName = createObject("java","javax.management.ObjectName");
if(urlString != "") {
    var JMXConnectorFactory = createObject("java","javax.management.remote.JMXConnectorFactory");
    var JMXServiceURL = createObject("java","javax.management.remote.JMXServiceURL");
    var c = JMXConnectorFactory.connect(JMXServiceURL.init(urlString), javacast("null",""));
    var mbs = c.getMBeanServerConnection();
} else {
        var mbs = ManagementFactory.getPlatformMBeanServer();
}
         request.debug(mbs.getMBeanCount());
try{
    for(domain in mbs.getDomains()) {
    var name = ObjectName.init( domain & ":*" );
         var beans = mbs.queryMBeans( name, javaCast("null",""));
        request.debug(domain);
         for(bean in beans.toArray()) {
        request.debug(bean.getObjectName().getKeyProperty("type"));
        request.debug(bean.getClassName());
        request.debug(bean.getObjectName().getKeyPropertyList());
         }
    }
} catch (any e) {

}
if(urlString != "") {
    c.close();
}

reading content from a jar from inside an Ant Javascript script task

Here's another handy little snippet for reading the content from a jar file while inside a javascript Ant <script> tag (in this example, reading the property file that is inside the ant-contrib jar@/net/sf/antcontrib/antcontrib.properties):

<script language="javascript">
    <![CDATA[
    importPackage(Packages.java.io);
    var antprops = project.getClass().getResource('/net/sf/antcontrib/antcontrib.properties');
    var inis = antprops.openStream();
    var br = new BufferedReader(new InputStreamReader(inis));
    while (null != (line = br.readLine())) {
     print(line);
    }
    ]]>

</script>

getting the current version of ant-contrib from inside Ant

Here's a simple little bit of code for getting the version of ant-contrib running in Apache Ant.

This uses the <script> task, although it would be just as easy (technically easier) to use the java task.

Mostly it's just kind of a useful example doing something java-ish (calling another classes main method) from inside the script tag:

<script language="javascript">
    <![CDATA[
    importClass(Packages.net.sf.antcontrib.AntContribVersion);
    var ver = new AntContribVersion.main(java.lang.reflect.Array.newInstance(java.lang.String, 1));
    ]]>

</script>

the tale of two plugins, or: the tale of one plugin from two providers

I work on an Eclipse plugin called CFEclipse.

CFEclipse has a built-in unit testing plugin, but it's old and pales in comparison to another available unit testing plugin called MXUnit.

So I wanted to replace the built-in plugin with the MXUnit plugin.

I needed to bundle MXUnit with CFEclipse, and still allow people to update from MXUnit if a newer version came out before I could bundle it with CFEclipse, however.

I thought that adding a "discovery" child to the "url" node (pointing at the MXUnit update site) as well as adding an "includes" node to the feature.xml would get me there:

<url>
<update label="CFEclipse Update Site" url="http://www.cfeclipse.org/update"/>
<discovery label="CFEclipse discovery site" url="http://cfeclipse.org/update"/>
<discovery label="MXUnit discovery site" url="http://mxunit.org/update"/>
</url>

<includes
id="org.mxunit.eclipseplugin.feature"
version="0.0.0"
search-location="both"
/>

I figured thusly because that's what I could find searching the web using terms like: "including 3rd party plugins" or "using two update sites" and whatnot.

The only problem was, this seemed to lock anyone who installed the bundled CFEclipse + MXUnit into whatever version of MXUnit we bundled (specifying 0.0.0.0 as a version number didn't help).

I figured if I could specify a revision range for MXUnit, that should "unlock" updates from the main MXUnit update site.

Unfortunately, looking through the docs, it appeared you could specify revision ranges for dependencies, but not for plugins you include in the feature.xml.

Back to the search-board!

The magic search string was: "feature.xml includes version ranges"

Which led me to this:

http://www.eclipse.org/forums/index.php?t=msg&&th=157425&goto=513692

Which had the following info:

There are two approaches, the first is to change the feature to require the plug-in instead of include it. This gets you the old update style ranges of equivalent[1.2.3, 1.3.0), compatible[1.2.3, 2.0.0), or greaterOrEqual. However, PDE/Build currently only builds included plug-ins, not required ones. So you would need to build the bundles separately and then have them (and their metadata) available to the product build.

The other and perhaps simpler option is for the feature to have a p2.inf beside the feature.xml. The p2.inf can add requirements to the feature, and they replace the generated requirements that came from included plug-ins if the name and namespace are the same.

feature: include org.eclipse.foo 0.0.0 p2.inf: requires.1.namespace = org.eclipse.equinox.p2.iu requires.1.name = org.eclipse.foo requires.1.range = [1.0.0, 2.0.0)

If you are changing the requirement ranges for include features, remember that the name for a feature's IU has ".feature.group" appended to it.

http://wiki.eclipse.org/Equinox/p2/Customizing_Metadata

Ah ha! I opted for the p2.inf approach, although I think the former might be better if you have to support pre Eclipse 3.3 plugins. Option two was definitely the easier of the two, too. :)

After adding the p2.inf, things worked like I'd wanted, where the update to MXUnit can come from either the main MXUnit update site or the CFEclipse update site.

This decoupling allows the end users to choose when and where to get their MXUnit updates, vs. forcing them into using whichever version CFEclipse ships with.

Score!

Ironic that it took a few hours of dicking around with stuff and searching to find a 3 line solution, but that's Eclipse development. Things that are simple in retrospect can be rather difficult to unearth initially.

I think this is a result of the size of the Eclipse codebase, and the constantly changing nature of it- neither of which would I trade in exchange for easier docs.

If Eclipse was closed source, I'd sing a different tune.

And targeting a different platform.

mxunit cfe template

<cfcomponent displayname="Test${component}" extends="mxunit.framework.TestCase">

<cffunction name="setUp" returntype="void" access="public">
        <cfset variables.${component} = createObject("component","${componentPath}") />
</cffunction>

    <cffunction name="dumpvar" access="private">
        <cfargument name="var">
        <cfdump var="#var#">
        <cfabort/>
    </cffunction>

    <cffunction name="test${method}">
        <cfscript>
            variables.${component}.${method}(${cursor});
        
</cfscript>
    </cffunction>

</cfcomponent>

Hung JBoss/Tomcat instances and "ignored" shutdown requests

I kept hearing about how people were using "kill" in Tomcat shutdown scripts, as they'd shutdown an instance but it would still be running. Further attempts to shutdown after the initial one would say something to the effect of "already shut down" or some-such.

I hadn't been experiencing this, and said so publicly-- at which point I promptly started to experience this locally when running certain unit tests.

It sorta bugged me, and having a semi-reproducible set up, I figured what the hell, might as well troubleshoot.

For Schlitz and giggles, I cycled httpd after causing a "hung" process, and what do you know, JBoss finished shutting down.

I think this is something in the way folks have AJP set up. I'm playing with some settings, namely the "connectionTimeout" attribute in the Tomcat AJP connector config, and the "ping" attribute for mod_proxy.

I'll update this when I have a chance to see if one of them worked-- I'm troubleshooting while doing real work, so I don't shut down often. =]

Update:

Well, so far, after adding the connectionTimeout attribute to the AJP connector in deploy/jbossweb.sar/server.xml, I haven't had the shutdown problem.

I'm unconvinced so far, but so far, so good.

Here are some mod_proxy docs:

http://httpd.apache.org/docs/2.3/mod/mod_proxy.html

Reinstalling X11 on OS X 10.5

My HD died a while back, and I thought I was all set with the replacement from Apple, but turns out it didn't have my X11 stuphs.

Kept getting errors like:

Jun 30 18:02:02 den org.x.startx[17633]: Xquartz: Could not find a new enough X11.app LSFindApplicationForInfo() returned
Jun 30 18:02:02 den org.x.startx[17633]: X11.app = /Applications/Utilities/X11.app
Jun 30 18:02:02 den org.x.startx[17633]: Version = 2.1.5 (2158000), Expected Version >
2.3.0 or 2.1.6

I don't know where the hell my install disks are, so I thought I was hosed till I found 'em.

Nope!

Turns out you can re-install, and even upgrade, the Apple X stuff using the creators site:

http://xquartz.macosforge.org/trac/wiki/WikiStart

Woohoo!

Converting a java resultset into a Railo CF query

It's pretty easy:

q = createObject("java", "railo.runtime.type.QueryImpl").init(resultset,"YourQueryName");

And that's it!

microsoft-sqljdbc.jar deployment errors on JBoss

While deploying your application on jboss you may run into a zip error type deal, something like this:

Caused by: java.lang.Error: Error visiting DelegatingHandler@1463636387[path=cf.ear/railo.war/WEB-INF/lib/microsoft-sqljdbc.jar context=file:/home/coldshen/deploy2/ real=file:/home/coldshen/deploy2/cf.ear/railo.war/WEB-INF/lib/microsoft-sqljdbc.jar]

Which means the VFS deployer just choked on the (IMO) malformed microsfot jdbc driver jar [Ed Note: yes, I left the spelling error in there, cuz I'm cool like that].

See this thread for long, technical discussion:

http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4182061#4182061

And the solution is to edit your vfs.xml file (given the context location above, the path is /home/coldshen/deploy2, you'll have to edit yours) and add this entry to the VFSCache bean:

<entry>
<key>/home/coldshen/deploy2/</key>
<value><inject bean="VfsNamesExceptionHandler"/></value>
</entry>

Which basically tells JBoss that there's a fscked-up jar in, or under, that directory.

The vfs.xml file should be located at: {jboss_home}/server/{your_server}/conf/bootstrap/vfx.xml

deploying your EAR or WAR on JBoss 5 from another location on disk

Sometimes it is a pain in the ass to keep your crap in the deploy directory. There used to be docBase and whatnot, but that nifty stuff is ignored mostly by JBoss 5, since it's got it's own nifty way of doing things.

So, if you'd like to easily keep your code separate from your appserver (mostly a developer's want-- on production, most this crap doesn't matter), you can do this:

Edit {jboss_home}/server/{your_server}/conf/bootstrap/profile-repository.xml to have something like this:

...
<bean name="SerializableDeploymentRepositoryFactory" class="org.jboss.system.server.profileservice.repository.SerializableDeploymentRepositoryFactory">
<property name="storeRoot">${jboss.server.base.dir}</property>
<property name="attachmentsRoot">${jboss.server.data.dir}/attachments</property>
<property name="applicationURIs">
<array elementClass="java.net.URI">
<value>${jboss.server.home.url}deploy</value>
<value>file:///path/to/your/deploy/dir</value>
</array>
</property>
<property name="serializer"><inject bean="AttachmentsSerializer"/></property>
<property name="deploymentFilter"><inject bean="DeploymentFilter" /></property>
<property name="mainDeployer"><inject bean="MainDeployer"/></property>
<property name="checker"><inject bean="StructureModificationChecker"/></property>
<depends>ProfileServicePersistenceDeployer</depends>
</bean>...

See that line? : file:///path/to/your/deploy/dir ?

Yup, that's the magic line.

Your deploy directory should just contain the WARs or EARs, and they should be named like "yourapp.war" or "yourapps.ear". They can be exploded or not. Heh. "Exploded". I like that. Anyways...

That's it. JBoss5 should now deploy "stuff" from wherever you specified.

using nmap to get a list of DNS host names

Sometimes you want to update your hosts file, but you don't remember what all your hostnames are, or some have been added that didn't follow whatever process you've got in place, so are unlisted.

This little deal will list all the host names for a particular range (in this example, 192.168.1.0 through 192.168.1.255):

nmap -sL 192.168.1.0/24 | tr -d '()' | awk '{print $3 "\t" $2}'

You obviously need nmap, tr, and awk for this to work.

End Of Line

Speeding up JBoss 5 applicaiton deployment

I've mentioned before the trick of turning off the AOP scanner to quicken deployment, but I've found another way, that I like a lot better.

The delays in starting up are worst for CF apps, because they've got so many classes, and so you may have noticed that the more classes you've saved, the longer it takes.

For a while I had a script that cleared out the cfclasses folder before each start, but that was soooo hackish. More of a kludge, actually. Fine for development tho.

I've found that if you use a jboss-structure.xml file in your META-INF (I put it in my ear/META-INF), jboss will use it to determine what and where to deploy stuff, along with class paths and whatnot. This disables the recursive scanning jboss normally does, and makes startup times acceptable again.

Example 1 (ear file with libs in each war):

<structure>

    <context>
        <path name="railo.war" />
        <metaDataPath>
            <path name="WEB-INF" />
        </metaDataPath>
        <classpath>
            <path name="/railo.war/WEB-INF/lib" suffixes=".jar" />
        </classpath>
    </context>

</structure>

Example 2 (ear file with consolidated libs folder):

<structure>

    <context>
        <path name="widgets.war" />
        <metaDataPath>
            <path name="WEB-INF" />
        </metaDataPath>
        <classpath>
            <path name="/lib" suffixes=".jar" />
        </classpath>
    </context>

    <context>
        <path name="sprockets.war" />
        <metaDataPath>
            <path name="WEB-INF" />
        </metaDataPath>
        <classpath>
            <path name="/lib" suffixes=".jar" />
        </classpath>
    </context>

</structure>

multiple CF instances in an EAR

To continue on my series about deploying CF apps, I'm going to cover a nice method of doing multiple instances, using an EAR deployment.

You'll want to start off with your EAR folder. For this example we'll use Railo, cuz it's the best, but the others work similarly.

I'll call this EAR railo.ear. So I make a folder called railo.ear, and within it I create a folder called META-INF, and then inside that I create a file called application.xml.

Into railo.ear/META-INF/application.xml I put this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE application PUBLIC "-//Sun Microsystems, Inc.//DTD J2EE Application 1.2//EN" "http://java.sun.com/j2ee/dtds/application_1_2.dtd">
<application id="Application_ID">
<display-name>RailoApps</display-name>
<description>Railo Applications</description>
<module id="widgets">
<web>
<web-uri>widgets.war</web-uri>
<context-root>/widgets</context-root>
</web>
</module>
<module id="sprockets">
<web>
<web-uri>sprockets.war</web-uri>
<context-root>/sprockets</context-root>
</web>
</module>
</application>

You're probably wondering what the widget and sprocket wars are. They are the names of our (in this example) Railo CF applications (widgets.com and sprockets.com).

We'll start off with a normal Railo war install. You've got WEB-INF/web.xml and a bunch of libraries in WEB-INF/libs. What we're going to do is move the {railo.war}/WEB-INF/libs folder to our EAR folder ({railo.war}/WEB-INF/libs becomes railo.ear/libs). Next we'll rename the railo.war to widgets.war, and move it under our EAR (ex.: railo.ear/widgets.war). It will be a pretty lonely folder, there's nothing in it besides WEB-INF/web.xml.

Now, I like using one web admin for all the instances (DSNs and whatnot only need to be configured once, and any CF apps in the ear will pick them up), so this is how I change the WEB-INF/web.xml file configuration param for Railo to achieve this: configuration ../META-INF/railo-web/ Configuraton directory

This tells Railo to store it's "web" configuration information in railo.ear/META-INF/railo-web.

Next we copy the widgets.war directory to sprockets.war. That's it. (Make as many copies as you want (we're sticking to widgets and sprockets), just give them unique directory names. Each one of these will be an instance. Good thing we're using one configuration location for all of them, neh?)

I like storing the configuration with the EAR, in the future this might come in handy...

Anyways, now move that EAR into your application server's deployment directory, and fire up your container/server.

If all goes well, you should see some output about railo generating it's flex stuff and whatnot (almost all of it will end up in railo.ear/libs), and see the widgets and sprockets contexts load up.

If you really did see them load up, then you can browse to each application using a URL format like this: http://your.host.name:8080/widgets and http://your.host.name:8080/sprockets. (See, the name of the directory becomes the context name. Neat, nuh?)

Assuming that worked, you're done! (with this part... next comes hooking them up to Apache.)

installing multiple CF engines into one EAR for compatibility testing

We're going to cover installing cfusion, opendb, and railo into a single EAR, for compatibility testing and whatnot.

This is most useful on a system with softlinks (symlinks), so windows users are kinda hosed (yeah yeah, MS has "had them" since 2K-- let's not go there).

You don't *need* the symlinks, but only Railo seems to be able to pick up an initial request to a mapped resource-- the others need at least one physical file first (correct me if I'm wrong, people) -- so you're stuck with multiple copies of your code, otherwise.

Now for the meat: there's not much.

Create an ear for your engines (ex.: cfengines.ear) -- this is an empty folder, for now (yes, with the dot -- on windows systems, you can use a dash too, I reckon -- bleh).

Next create the META-INF folder within the cfengines.ear folder. Case matters.

Then create your application.xml file in the META-INF folder. (Ex.: cfengines.ear/META-INF/application.xml) put something like this into it:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE application PUBLIC "-//Sun Microsystems, Inc.//DTD J2EE Application 1.2//EN" "http://java.sun.com/j2ee/dtds/application_1_2.dtd">
<application id="Application_ID">
<display-name>CFEngines</display-name>
<description>CFEngines</description>
<module id="railo">
<web>
<web-uri>railo.war</web-uri>
<context-root>/railo</context-root>
</web>
</module>
<module id="cfusion">
<web>
<web-uri>cfusion.war</web-uri>
<context-root>/cfusion</context-root>
</web>
</module>
<module id="openbd">
<web>
<web-uri>openbd.war</web-uri>
<context-root>/openbd</context-root>
</web>
</module>
</application>

And then, well, start your engines! (as in, start downloading them).

After you've got the ones you need (you're looking for WAR files, obviously), you're going to want to put them in expanded format within your EAR.

We like exploded format so that we can do live editing of CF files. This means you unzip the WAR file (it's just a zip, so you can change the name to railo.war.zip, for instance) into a .war folder in the ear folder.

Ex: cfengines.ear/openbd.war/, cfengines.ear/cfusion.war, etc..

If you're thinking by now that this sounds lot like my "how to install Railo as an EAR", you're pretty observant.

Move the ear into your deploy folder (for jboss, it's {jboss.home}/servers/{server}/deploy, for instance) and start your container. That's it!

Yes, it's really that easy.

This will provide you with http://your.host.here/railo for railo, http://your.host.here/openbd for openbd, and http://your.host.here/cfusion for Adobe CF (admin would be at http://your.host.here/cfusion/CFIDE/administrator/index.cfm, for example -- the index.cfm at the end is important!).

The only down side is that these CF engines ('cept Railo) need the CF files in their WAR directory. At least one file-- after you hit a "real" one, you can take advantage of mappings and whatnot from anywhere on your drive.

If this doesn't seem to make sense, try it out, you'll see what I mean.

I'll cover the Apache URL-rewriting from this point, in another entry.

Testing jgroups communication (multicasting)

Basically we're following this:

http://www.jgroups.org/manual/html/ch02.html#ItDoesntWork

The main tools are included in the "all" JBoss server lib dir-- jgroups.jar (ex:{jbossdir}/servers/all/bin/jgroups.jar).

CD into that directory, and try this stuff:

Make sure your machine is set up correctly for IP multicast. There are 2 test programs that can be used to detect this: McastReceiverTest and McastSenderTest. Start McastReceiverTest, e.g.

java -cp ./jgroups.jar org.jgroups.tests.McastReceiverTest -mcast_addr 224.10.10.10 -port 5555
        

Then start McastSenderTest:

java -cp ./jgroups.jar org.jgroups.tests.McastSenderTest -mcast_addr 224.10.10.10 -port 5555
        

If you want to bind to a specific network interface card (NIC), use -bind_addr 192.168.0.2, where 192.168.0.2 is the IP address of the NIC to which you want to bind. Use this parameter in both sender and receiver.

You should be able to type in the McastSenderTest window and see the output in the McastReceiverTest. If not, try to use -ttl 32 in the sender. If this still fails, consult a system administrator to help you setup IP multicast correctly. If you are the system administrator, look for another job :-)

Other means of getting help: there is a public forum on JIRA

for questions. Also consider subscribing to the javagroups-users mailing list to discuss such and other problems.

2.9. The instances still don't find each other !

In this case we have to use a sledgehammer (running only under JDK 1.4. and higher): we can enable the above sender and receiver test to use all available interfaces for sending and receiving. One of them will certainly be the right one... Start the receiver as follows:

java -cp ./jgroups.jar org.jgroups.tests.McastReceiverTest1_4 -mcast_addr 228.8.8.8 -use_all_interfaces
        

The multicast receiver uses the 1.4 functionality to list all available network interfaces and bind to all of them (including the loopback interface). This means that whichever interface a packet comes in on, we will receive it. Now start the sender:

java -cp ./jgroups.jar org.jgroups.tests.McastSenderTest1_4 -mcast_addr 228.8.8.8 -use_all_interfaces
        

The sender will also determine the available network interfaces and send each packet over all interfaces.

This test can be used to find out which network interface to bind to when previously no packets were received. E.g. when you see the following output in the receiver:

java  -cp ./jgroups.jarorg.jgroups.tests.McastReceiverTest1_4 -mcast_addr 228.8.8.8 -bind_addr 192.168.168.4
            Socket=0.0.0.0/0.0.0.0:5555, bind interface=/192.168.168.4
            dd [sender=192.168.168.4:5555]
            dd [sender=192.168.168.1:5555]
            dd [sender=192.168.168.2:5555]
        

you know that you can bind to any of the 192.168.168.{1,2,4} interfaces to receive your multicast packets. In this case you would need to modify your protocol spec to include bind_addr=192.168.168.2 in UDP, e.g. "UDP(mcast_addr=228.8.8.8;bind_addr=192.168.168.2):..."

Setting up multicasting can be a PITA if you don't control your network. Luckily, we do, so it's no big deal, but there are a lot of things to check if it's not working.

I'd start with verifying that multicast forwarding is enabled on your NIC, and in your configs (this varies by OS, but google is quite helpful). Then move onto the rest of your network (firewalls, routers, etc.).

Start with the firewall: On a CentOS 5 box, you'll need to tweak the iptables config (/etc/sysconfig/iptables) to allow UDP traffic on the right interfaces.

Here's an example (put it under the existing udp stuff in sysconfig/iptables, which BTW, should also give you your UDP mcast addr (...-p udp --dport 5555 -d 2xx.0.0.x)):

-A RH-Firewall-1-INPUT -p udp -i eth3 -m udp --dport 4000:6000 -j ACCEPT

The above says "open ports 4000:6000 on the eth3 interface", basically. For my purposes, eth3 is a NIC dedicated to back-end private network traffic only. Having a separate NIC for inter-server communication is really tits.

After you add that line, you'll need to reload iptables:

iptables-restore < /etc/sysconfig/iptables

Depending on how you decided to have your nodes talk to each other, you may need to configure some stuff in jgroups-channelfactory-stacks.xml (jgroupschannel-factory.sar) - see this. I used something along these lines:

<FD timeout="10000" max_tries="5" shun="true"></FD>

Configuring jgroups for jboss AS 5 is easy as pie, here's some info for params and whatnot:

Isolation and JGroups ChannelFactory and Shared Transport in JBoss AS 5 and Buddy Replication and Session Data, although I had better links a while ago. Eh, those should get you going.

Yesh, just a copy/paste entry, mostly, but what the hell.

More Entries

BlogCFC was created by Raymond Camden. This blog is running version 5.9.3.000. Contact Blog Owner