Fotolia_65716003_XS.jpg

What’s the problem?

I like to keep my system up to date, and I depend on many Homebrew packages on my OS X machine. Homebrew allows for this but I:

  • want it automated
  • want it to delete old versions that I am no longer using

How did I solve it?

First, I added this into my .zshrc (could be in your .profile if you use Bash):

1
2
3
4
5
6
7
8
9
10
11
12
13
function brew_update() {
brew update
brew upgrade --all
ruby $HOME/remove_old_brews.rb
}
CURR_DATE=`date '+%Y-%m-%d'`
LAST_DATE=`head -n 1 $HOME/.brew_update_date 2>/dev/null`
if [ "$CURR_DATE" != "$LAST_DATE" ]; then
echo $CURR_DATE > $HOME/.brew_update_date
echo Updating Homebrew...
brew_update
fi

Then, I created remove_old_brews.rb in my home directory:

Wait, what?!

Ok, first the shell will check the current date and compare it with a date stored in a .brew_update_date file. If they differ, it immediately updates the file (so I can open another Terminal while the update is in progress), then it calls brew_update.

brew_update tells Homebrew to update its index, then upgrade all out of date packages. Finally, brew_update calls remove_old_brews.rb

remove_old_brews.rb looks at all installed packages in /usr/local/Library/LinkedKegs and finds packages with more than 1 version installed. For those, it finds whichever ones are not the currently linked version and removes them.

Things to consider

This is tuned for my workflow, but yours may differ. What I wanted was:

  • update the first time I open Terminal in a day
    • meaning if I really need a Terminal, I can just open another and the 2nd one won’t update
  • keep what was updated at the front of my attention (which is why I didn’t just put it into cron)

And that’s about it.

Comment and share

Fotolia_81329697_XS_T.png

Some Background

WebSphere controls whether applications (EARs and WARs) are in PARENT_FIRST or PARENT_LAST classloading mode by its deployment.xml. RAD, or Rational Application Developer, has tools to generate this, as does the application server itself, but the Eclipse plugins do not at the time of this writing. So how do you configure your applications?

Wait, what does the classloading mode do?

Simply, when your application attempts to load a class, say IOUtils from Apache Commons IO, the JVM needs to know what to do when it finds multiple classes with the same fully qualified name. You could have classes provided by your application server, global JARs that you have put into your application server, and JARs in your application.

_PARENT_FIRST _classloading means take classes found in WebSphere (the parent), or global JARs first. So if you bundle a version of Apache Commons IO that doesn’t match the parent version, your application will run with the parent version instead of your application’s version.

_PARENTLAST classloading means prefer your application’s first.

So what’s the problem?

Imagine this scenario:

  • Your servers have global JARs setup that specific applications running in the same WebSphere profile require
  • You start a new application in your local development environment and you don’t realize the server has overridden certain JARs
  • You bundle newer versions of those JARs in your application
    So, with the “It works on my machine” stamp of approval you push to your servers only to find… failure.

There are plenty of other scenarios that could lead to an issue as well.

What’s the silver bullet?!

Unfortunately, there is no silver bullet. You may want to re-evaluate having shared libraries, update their versions, change the classloading mode of your application, or use a different WebSphere profile. The right answer really depends on your environment, but if changing the classloading mode is right for you, read on!

Changing the classloading mode

There are a few ways to make this change:

  • Deploy your application to WebSphere and update the configuration in the admin console (or wsadmin)
  • Use RAD (Rational Application Developer) to change it, if you have RAD
  • Or, use a new tool that I’ve created!

Generating deployment.xml in WebSphere

To obtain a deployment.xml from WebSphere:

  1. Build your application as an EAR
  2. Manually install it to WebSphere (via your admin console at http://localhost:9060/ibm/console for example)
  3. Open your application in the admin console and configure your EAR’s classloader mode
  4. Use Manage Modules to configure the WARs’ classloader modes
  5. Save your changes to WebSphere
  6. Export your application from the admin console as an EAR
  7. Copy its ibmconfig with deployment.xml deeply nested in it

Generating deployment.xml in RAD

Generating deployment.xml in RAD is much easier:

  1. Right click your EAR
  2. Go to Java EE -> Open WebSphere Application Server Deployment
  3. Scroll to the bottom and configure classloader settings as desired

Comparing WebSphere’s generated deployment.xml to RAD’s

Updating the configuration in WebSphere generates a deployment.xml that you may not want to re-use. Let’s take a look at the differences:

WebSphere’s version

deployment.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version=“1.0” encoding=“UTF-8”?>
<appdeployment:Deployment xmlns:appdeployment=“http://www.ibm.com/websphere/appserver/schemas/5.0/appdeployment.xmi“ xmlns:xmi=“http://www.omg.org/XMI“ xmi:version=“2.0” xmi:id=“Deployment_1428026415557”>
<deployedObject xmi:type=“appdeployment:ApplicationDeployment” xmi:id=“ApplicationDeployment_1428026415557” deploymentId=“0” startingWeight=“1” binariesURL=“$(APP_INSTALL_ROOT)/WIN-F8QH15674T8Node02Cell/JpaExample.ear” useMetadataFromBinaries=“false” enableDistribution=“true” createMBeansForResources=“true” reloadEnabled=“false” appContextIDForSecurity=“href:WIN-F8QH15674T8Node02Cell/JpaExample” filePermission=“..dll=755#..so=755#..a=755#..sl=755” allowDispatchRemoteInclude=“false” allowServiceRemoteInclude=“false” asyncRequestDispatchType=“DISABLED” standaloneModule=“false” enableClientModule=“false”>
<targetMappings xmi:id=“DeploymentTargetMapping_1428026415557” enable=“true” target=“ServerTarget_1428026415557” />
<modules xmi:type=“appdeployment:WebModuleDeployment” xmi:id=“WebModuleDeployment_1428026415557” deploymentId=“1” startingWeight=“10000” uri=“JpaExampleWeb.war” classloaderMode=“PARENT_LAST” containsEJBContent=“0”>
<targetMappings xmi:id=“DeploymentTargetMapping_1428026415558” target=“ServerTarget_1428026415557” />
<classloader xmi:id=“Classloader_1428026415558” />
</modules>
<classloader xmi:id=“Classloader_1428026415557” mode=“PARENT_LAST” />
<properties xmi:id=“Property_1428026415557” name=“metadata.complete” value=“false” />
</deployedObject>
<deploymentTargets xmi:type=“appdeployment:ServerTarget” xmi:id=“ServerTarget_1428026415557” name=“server1” nodeName=“WIN-F8QH15674T8Node02” />
</appdeployment:Deployment>

RAD’s version:

deployment.xml
1
2
3
4
5
6
7
<?xml version=“1.0” encoding=“UTF-8”?>
<appdeployment:Deployment xmlns:appdeployment=“http://www.ibm.com/websphere/appserver/schemas/5.0/appdeployment.xmi“ xmlns:xmi=“http://www.omg.org/XMI“ xmi:version=“2.0” xmi:id=“Deployment_1423511656329”>
<deployedObject xmi:type=“appdeployment:ApplicationDeployment” xmi:id=“ApplicationDeployment_1423511656329” startingWeight=“10”>
<modules xmi:type=“appdeployment:WebModuleDeployment” xmi:id=“WebModuleDeployment_1423511656329” startingWeight=“10000” uri=“JpaExample.war” classloaderMode=“PARENT_LAST” />
<classloader xmi:id=“Classloader_1423511656329” mode=“PARENT_LAST” />
</deployedObject>
</appdeployment:Deployment>

The differences

Primarily, the WebSphere version includes node/cell specifics. If you take that version and deploy to a different server, you will end up with new folders in your profile/installedApps directory. This doesn’t cause any issues (that I’ve experienced) but its annoying.

A better solution for non-RAD users

If you take a look at the RAD version, its pretty basic and just lists the applications deployed and which classloading mode they are in. The ids are a standard format with the time after them.

So, assuming you are not using anything else in deployment.xml, this file is easy to reproduce! And to make it easier, I created a command line application to do it for you!

https://github.com/craigstjean/WebSphere-Deployment-Xml-Tool

To use it, invoke the JAR, passing it your application.xml as the first parameter, followed by either:

  • Nothing (which shows you its menu)
  • list (lists the EAR and all web application’s classloading mode)
  • set parent first (sets the EAR and all web applications to PARENT_FIRST)
  • set parent last (sets the EAR and all web applications to PARENT_LAST)
    For example:
1
java -jar WebSphere-Deployment-Xml-Tool.jar C:\workspace\MyProject\MyEar\META-INF\application.xml set parent last

And that’s it!

If you have any troubles with it, please create a GitHub issue and I’ll take a look!

Comment and share

Fotolia_62142043_XS-300x228.jpg

Did you know you can run WebSphere Application Server in development mode, which optimizes it for less powerful hardware and for applications which see frequent updates? It’s actually quite easy, whether you are creating a new profile or working with an exciting one!

Creating a New Profile with the Profile Management Tool

If you are creating a new profile, via the Profile Management Tool (or PMT), just make sure you select these two boxes:

  1. Use the “Advanced profile creation” mode
    2015-03-20 10_57_44-Profile Management Tool 8.5
    This allows you to tweak some very simple settings that you may be interested in, I recommend all people using PMT to create their profiles in this mode.
  2. Switch “Server runtime performance tuning setting” to “Development”
    2015-03-20 11_03_18-Profile Management Tool 8.5
  3. Then just finish the wizard with the settings you want!

Creating a New Profile via the Command Line manageprofiles Tool

For those command-line junkies like myself, creating a new profile via manageprofiles in development is also extremely easy. Simply add this flag to your -create parameter list:

-isDeveloperServer

That’s it! To read more about the parameters for manageprofiles, see here.

Modifying a Profile via the WebSphere Admin Console

If you’ve already created your profile, and want to simply enable development mode, simply log into the admin console and change it! It goes like this:

  1. Go to the WebSphere Administrative Console (e.g. http://localhost:9060/ibm/console)
  2. Log in

    1. Tip: If you do not have security enabled, just click Log In
  3. Drill into WebSphere application servers
    2015-03-20 11_08_46-WebSphere Integrated Solutions Console

  4. Drill into your server (e.g. server1)
    2015-03-20 11_09_01-WebSphere Integrated Solutions Console
  5. And check the following boxes:

    1. Run in development mode
    2. Parallel start
    3. Start components as needed
      2015-03-20 11_09_09-WebSphere Integrated Solutions Console
  6. Then click Save, and restart your server!

Modifying a Profile via the Command Line wsadmin Tool

Enabling development mode on an existing server is the most complicated choice, but luckily it is still pretty straight forward. Just follow these steps:

  1. Start your server (via Eclipse/RAD/RSA/Other IDE, or by command line)

    1. To start by command line, open your command prompt
    2. cd into your profile’s bin directory (e.g. C:\Profiles\MyAwesomeProfile\bin)
    3. startServer.bat server1 (or, ./startServer.sh server1 if you are not on Windows)
  2. With the command prompt in the bin directory (from the above steps), execute the following:

    wsadmin.bat server1
    set server [$AdminConfig getid /Server:server1/]
    $AdminConfig modify $server "{developmentMode true}"
    $AdminConfig modify $server "{parallelStartEnabled true}"
    $AdminConfig save
    quit
  3. Then, just restart your server!

    1. Tip: You can use stopServer.bat server1 to do this too (or ./stopServer.sh server1)
      Enjoy!

Comment and share

  • page 1 of 1

Craig St. Jean

Father, programmer, constant learner, @pluralsight author


Software Architect