Jul 15, 2010

Maven - Sun JAR Issues (javamail, jms, jmx, jdmk, persistence)

Problem

Compiling fails because of dependencies related to Sun, such as javamail, jms, jmx. These failures have some of the symptoms listed below.

Background. Many of Sun's Java projects do not have licenses that allow for redistribution. Basically, their stuff is somewhat "locked down." To get it, you have to click through a Software License Agreement; meaning, their libraries can, at times, be a pain to download. Historically, their JARs have not been in public Maven Repositories. As such, Maven tends not to automatically download Sun dependencies. Nowadays, they are available in the default repository . . . supposedly. However, over here IN REALITY, that doesn't really work.

If you have "Maven: The Definitive Guide," read page 73 under the section "Adding J2EE Dependencies" for related information.

Symptoms

Some symptoms of this problem I saw while trying to solve it include:

  • Failed to resolve artifact
  • Missing:
    ----------
    1) javax.persistence:ejb:jar:3.0-public_review
  • [INFO] Unable to find resource 'javax.persistence:ejb:jar:3.0-public_review' in repository JBoss Repository (https://repository.jboss.org/nexus/content/groups/public/)
  • error: error reading /Users/keving/.m2/repository/com/sun/jdmk/jmxtools/1.2.1/jmxtools-1.2.1.jar; cannot read zip file
  • error: error reading /Users/keving/.m2/repository/javax/mail/mail/1.4.1/mail-1.4.1.jar; cannot read zip file
  • error: error reading /Users/keving/.m2/repository/com/sun/jmx/jmxri/1.2.1/jmxri-1.2.1.jar; cannot read zip file
  • [INFO] Unable to find resource 'javax.jms:jms:jar:1.1' in repository central (http://repo1.maven.org/maven2)
  • [INFO] Unable to find resource 'javax.persistence:ejb:jar:3.0-public_review' in repository maven.springframework.org (http://maven.springframework.org/snapshot)
  • [INFO] Unable to find resource 'javax.persistence:ejb:jar:3.0-public_review' in repository central (http://repo1.maven.org/maven2)
  • Failed to resolve artifact. com.sun.jmx:jmxri:jar:1.2.1
  • Failed to resolve artifact. com.sun.jdmk:jmxtools:jar:1.2.1
  • Solutions

    I recommend solution 4, below. After an hour or two of Googling, reading and learning, my final course of action (Solution 4) was to first delete all the troubled Sun dependencies, then painstakingly download the right JARs directly from Sun/Oracle and install them in the local repository. Below, I have listed all the useful solutions I found and tried during my journey to finding a complete repair.

    Solution 1 - Fastest, Easiest Fix

    Simplest solution: change just one character in the POM fille... use version 1.2.14 instead of 1.2.15. So the log4j dependency section
    changes FROM:

    <dependency>
    <groupid>log4j</groupid>
    <artifactid>log4j</artifactid>
    <version>1.2.15</version>
    </dependency>

    TO:

    <dependency>
    <groupid>log4j</groupid>
    <artifactid>log4j</artifactid>
    <version>1.2.14</version>
    </dependency>

    Solution 2 - Quick Fix

    Next simplest solution: exclude Sun jars by adding the following exclusions to the Log4j dependency within the pom.xml file:

    Solution 3 - Ideal Fix (didn't work for me)

    Best Solution (but doesn't work...or at least I can't get it to work): Use the special repositories provided by Sun: add to POM.xml

    Supposedly, this repository is provided by Sun and contains the missing jars. Each one has a "Reference Implementation" of the underlying API. Somehow, this allows for a looser license so the code can be redistributed without clicking through an SLA. When I tried this, it only successfully installed 1 of the JARs--javamail.

    Solution 4 - Thorough Repair (my choice)

    This is the longer, yet more complete solution--get the actual jars from Sun/Oracle. I kept track of all the little things I did and listed them below, keeping as many things "cut and pasteable" as possible. These are the steps I took and the commands I happened to run along the way:

    Delete the jars from the local repository:

      rm -rf ~/.m2/repository/javax/persistence/ejb/
      rm -rf ~/.m2/repository/javax/jms
      rm -rf ~/.m2/repository/javax/mail
      rm -rf ~/.m2/repository/com/sun/jdmk
      rm -rf ~/.m2/repository/com/sun/jmx

    run maven again (at least to the compile phase) to see exactly which jars fail.

    cd [top-level project directory with pom.xml]
    mvn assembly:directory -Dmaven.test.failure.ignore=true

    then download any remaining, missing JARs directly from SUN. Here are the detailed steps I took, grouped by each type of jar. The exact links may change over time but the basic steps should be the same. Note that the jdmk and jmx jars both come in one download.

    JMS

    1. click here to download the JMS jar from Sun/Oracle, accept the Software License Agreement and download the jar
    2. unpack the zip archive (automatic on my machine to directory ~/Downloads)
    3. cd to the lib directory
    4. cd ~/Downloads/jms1.1/lib/
    5. install the jms jar into the local maven repository, using the following command

    JDMK - JMX Tools and/or JMXRI

    1. click here to download the JDMK jar from Sun/Oracle, accept the Software License Agreement and download the jar
    2. (Found on Sun's Java SE page for the JDMK/JMX project by choosing Download" under the "BINARY DOWNLOAD" section under "JMX 1.2.1 Reference Implementation")
    3. This zip will include jars for both jmxtools and jmxri. Unpack the archive(automatic on my machine to directory ~/Downloads)
    4. cd to the lib directory
    5. cd ~/Downloads/jmx-1_2_1-bin/lib/
    6. install both jars into the local repository, using the following commands

    Persistence

    1. click here to access the javax.persistence jar from sourceforge
    2. unpack the archive (automatic on my machine to directory ~/Downloads)
    3. cd to the lib directory
    4. cd ~/Downloads/hibernate-annotations-3.1beta5/lib/
    5. install the javax persistence jar into the local maven repository, using the following command

    JavaMail

    Java mail is now open source so you shold be able to pull it from the default Maven repository. If not, try adding Sun's repository (Solution 3) and seeing if that will pull down the javamail jar. Be sure to completely delete the javamail directory (~/.m2/repository/javax/mail) before running this.


    Summary / Tradeoffs

    Each solution I found, I didn't quite like for different reasons. Solution 4 was the first satisfying choice. Each of the previous approaches involved tradeoffs. The first one downgrades to an earlier version of Log4j and, clearly, they moved to 1.2.15 for a reason.. Maybe there are security patches. Maybe the difference is negligable. Either way, I don't want to deal with figuring it out. So, Solution 1 would be the quick and dirty fix I'd use a coworker who needed to get their environment working in a hurry but it's not something I'd choose as a long-term fix. Solution falls into a similar boat. I like that it doesn't downgrade, but it cuts out dependences that are probably there for a reason. Most of what I read indicated that those libraries are virtually unused. Still, to me, there their for a reason so although I'd prefer solution 2 over solution 1, I wouldn't use it long-term, either. Solution 3 didn't work for me. The claim was that this repository had all the magic jars required but it didn't turn out that way. Upon download, two of them failed the checksum--I couldn't figure out why--and the other two jars didn't appear to be in the repository at all. In fact, it seemed that the only thing I could get, error-free, was the javamail jar. Not good enough.

    Finally, the fourth solution allowed Log4j to remain at the latest version and keep all it's dependencies. Admittedly, it was far more tedious and took me about 20 minutes to complete. Hopefully, this detailed post will greatly reduce that time for at least one person out there. If that person is you, I hope you can have your cake (a complete solution) and eat it too (a quick solution)! Celebrate.

    Linux Equivalent of ipconfig renew and ipconfig release on Windows

    I've looked this up 3 times so I finally decided to jot it down so I don't forget it.

    Problem

    Can't remember the Linux commands equivalent to:
    ipconfig renew
    ipconfig release

    Symptoms

    • Your IP is assigned via DHCP on a Linux box
    • You've unplugged from one network and plugged into another and the old IP address hasn't cleared out
    • Don't want to shutdown/restart the interface you just want to refresh the DHCP settings

    Solution

    sudo /sbin/dhclient -r is equivalent to ipconfig release
    sudo /sbin/dhclient is equivalent to ipconfig renew
    sudo /sbin/ifconfig is equivalent to ipconfig
    
    The dhclient command broadcasts a DHCP message to your DHCP server, resulting in a new lease. A slower way to achieve the same result is to shutdown the interface and bring it back up via (assuming your target interface is eth0):
    sudo /sbin/ifdown eth0
    sudo /sbin/ifup eth0
    
    This same, slower approach can also be done graphically on RedHat by clicking System > Administration > Network, choosing your interface (eth0) and clicking deactivate followed by activate.

    Jun 15, 2010

    Rollback Subclipse - Revert Subversion Changes

    Problem

    You need to rollback/revert subversion to a previous version and you're using the Subclipse plugin for Eclipse (or Flash Builder 4, etc.) to do it.

    Symptoms

    • There have been many changes to your project. You want to "undo" all those changes, restoring your project to its former glory.
    • Choosing "Revert" only blew away your local changes. That's not good enough.
    • There's a particular point in the past where everything "worked" and you need to reset everything back to that revision.

    Solution

    1. Right click your top level project folder and choose "Team" > "Show History"
    2. Find the point in the past where things worked
    3. TIP: click the play button on the top left to "show the next 25" revisions
    4. Highlight all revisions AFTER the target revision
    5. Right click and choose "Revert changes from revision # to revision #"
    6. That's it. Commit your changes

    For me, the revision that worked was revision 3690. The revision I was on was 3765. So, I highlighted revisions 3691 to 3765, right clicked and chose "Revert changes from revision 3765 to 3691."

    From there, I wanted to keep certain changes so I right clicked my project folder and chose "Compare With..." > "Latest From Repository". This opened a view of every single file in the project that was altered. I double-clicked the files with useful changes, copied the changes I wanted over and saved the compare editor.

    After everything looked correct, I committed. Worked great.

    May 20, 2010

    Debug BlazeDS Tomcat Server in Eclipse!!!

    Warning: this post is dripping with awesome. Once you're able to get this working, you might go dancing in the street (I know I did!). Consider yourself warned.

    Problem

    You need to debug java code running on Tomcat as part of BlazeDS. You want to do this in Eclipse.

    Symptoms

    • You're tired of using logs, system outs, or other tom-foolery to debug the server-side code for your Flex application!
    • You tried to set this up but received the following error:
    • java.lang.NoSuchMethodError: org.eclipse.wst.common.componentcore.internal.resources.VirtualComponent.clearCache()V
    • You'd like to set a breakpoint and have server execution stop and jump to your breakpoint, even while executing RemoteObject code from Flex
    • Once you hit such a breakpoint, you want to be able to inspect variables and expressions and enjoy similar debugging pleasures

    Solution

    Note: In this process, I encountered the very common error:

    java.lang.NoSuchMethodError:

    org.eclipse.wst.common.componentcore.internal.resources
    .VirtualComponent.clearCache()V

    Fixing it simply required updating eclipse.

    I'll summarize the steps to getting debugging tomcat in eclipse to work as follows:

    1. Open the Server View, right click and create a New Server
    2. Point it to your /blazeds/tomcat folder (do not add any projects yet)
    3. Right Click the new server and choose "Open"
    4. Make sure your settings match this screenshot
    5. NOTE: if the "Sever Location" section is disabled, that means you added a project in step 2. Delete this sever and start over without adding any projects.


    Better yet, just follow this excellent and detailed blog titled Setting up your BlazeDS (tomcat) server on Eclipse ( local ). It worked flawlessly.

    I credit the FlashBandit blog with opening my eyes to the fact that Setting Up a Basic BlazeDS Server with Debugging was even possible.

    Uninstall MySQL on Mac OS X (Leopard 10.5 or Snow Leopard 10.6)

    Problem

    You need to completely remove mysql from your system as easily as possible.

    Symptoms

    You want to do a clean delete and a fresh install because you don't want to deal with errors such as:
    • MySQL [your version] for Mac OS X can't be installed in this disk. A newer version of this software already exists on this disk.
    • [ERROR] Can't open the mysql.plugin table. Please run mysql_upgrade to create it.
    • [ERROR] Fatal error: Can't open and lock privilege tables: Table 'mysql.host' doesn't exist

    Solution

    Execute the following commands that I found here and here:
    sudo rm /usr/local/mysql
    sudo rm -rf /usr/local/mysql*
    sudo rm -rf /Library/StartupItems/MySQLCOM
    sudo rm -rf /Library/PreferencePanes/My*
    edit /etc/hostconfig and remove the line MYSQLCOM=-YES-
    sudo rm -rf /Library/Receipts/mysql*
    sudo rm -rf /Library/Receipts/MySQL*
    sudo rm -rf /var/db/receipts/com.mysql.*
    
    Maybe one day, if I'm feeling frisky, I'll come back and write a bash script to remove the MYSQLCOM line auto-magically. Maybe some magic involving sid or awk or something.

    May 7, 2010

    Fix Pixelbender Shader Compile Errors

    Today, I had a small pixelbender issue that I faced once before and forgot about it until I found the solution. Since this is the second time I've faced this, I decided to record the solution here.

    Problem

    Flex code, related to PixelBender, isn't compiling.

    Symptoms

    In Flex Builder / Flash Builder, I get the following errors:

    • 1046: Type was not found or was not a compile-time constant: Shader.
    • 1046: Type was not found or was not a compile-time constant: ShaderFilter.
    • 1172: Definition flash.display:Shader could not be found.
    • 1172: Definition flash.filters.ShaderFilter could not be found.
    • 1180: Call to a possibly undefined method Shader.
    • 1180: Call to a possibly undefined method ShaderFilter.

    Solution

    Clearly, these errors make no sense because both Shader and ShaderFilter are built-in classes distributed with Flash. Luckily, the solution is simple--you have to adjust your target Flash Player version. Make sure it's at least version 10:
    1. Right click your project and choose properties
    2. Go to the Flex Compiler section
    3. At the bottom, in the HTML wrapper section, check the Require Flash Player version box (which requires the Generate HTML wrapper file box to be checked)
    4. Enter at least version 10.0.0
    5. Celebrate!
    That's it. Here's a picture!

    May 4, 2010

    Install MySQL

    I just referenced this section of a file on my laptop because it has direct links and I was too lazy to think through installing mysql. Then, I decided to post it so I can link to it from another post I'm writing. Enjoy.

    Installation of MySQL v5.1

    1. Open the Safari browser then go to http://dev.mysql.com/downloads/mysql/5.1.html
    2. Download the latest version (today it's 5.1.46) either 32 or 64 bit (we use 32)
    3. Note: I recommend the DMG version, instead of the TAR archive because it has a handy pkg that, with one click, sets mysql server to run at startup.
      Snow Leopard (10.6):
      click the "Download" button under Mac OS X ver. 10.6 (x86, 32-bit), DMG Archive
      or
      Leopard (10.5):
      Mac OS X 10.5 (x86, 32-bit), Compressed DMG Archive
    4. On the next screen, you can ignore the login boxes by choosing

      "» No thanks, just take me to the downloads!"

      and select a mirror
    5. Double click on the mysql-5.1.46-osx10.6-x86.dmg file in the window opened by the download.
    6. Click the mysql-5.1.46-osx10.6-x86.pkg file to install mysql
    7. Optionally, once done, double click the "MySQLStartupItem.pkg" to automatically configure your Mac to launch the mysql server on startup
    8. Start the database by entering, /usr/local/mysql/bin/mysql –u root –p (no password needed).
    9. NOTE: if you get the error:
      “Can't connect to local MySQL server through socket '/tmp/mysql.sock'”
      Then, that means the mysql server is not running. One work-around to solve this problem is to enter a command similar to the following:
      sudo /usr/local/mysql/bin/mysqld_safe
      (enter your OS X login password, when prompted) Then, open a new terminal window and proceed
    10. List all databases by entering,
      SHOW DATABASES; 
    11. Create a new database,
      CREATE DATABASE myDatabase
    12. where myDatabase is the name of the new database.

    13. Use the database by entering, USE myDatabase
    14. Create a table in the new database by entering
      CREATE TABLE example_table (
               id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
               data VARCHAR(100),
               cur_timestamp TIMESTAMP(8)
             );
    15. Display the table by entering
      SHOW TABLES;
    16. Add a value to the table by entering
      INSERT INTO example_table (data) VALUES (‘the current time is’)
    17. View the all data in the table by entering
      SELECT * FROM example_table;
    18. In order to create users, enter
      CREATE USER ‘userBob’@’localhost’ INDENTIFIED BY ‘s3kr1tP4$$W0RD’;
    19. In order to grant permissions to users for local and remote connections to the database, enter
      GRANT ALL PRIVILEGES on myDatabase.* TO 'userBob'@’%’

    Mar 16, 2010

    Eclipse - Run / Debug - The Fast Way

    Ok. This was so awesome, I had to stop everything and blog about it, simply because every Eclipse user on earth should hear about this.

    Problem

    So, in Eclipse, I got fed up always clicking through a thousand menus to run my application. I'm using maven, so to run our project, I have to mouse over to our POM.xml, right click on it, mouse ALL THE WAY down to "Run As" (of course, I always forgetfully mouse over "Maven," instead), then mouse ALL THE WAY down to "Maven build," then I have 6-8 run configurations to choose from so I have to mouse ALL THE WAY over to the middle of the screen and pick one!

    Clearly, I HATE MOUSING. So I hunted down a better way.

    Now all I have to do is hit COMMAND + SHIFT + F11 (ctrl + F11 on windows) to run my last-used configuration. This command already works by default on plain Java files but when you start getting fancy with the run configurations . . . and Maven . . . and things . . . it doesn't function the same.

    Solution

    1. Hit COMMAND + , to open preferences (without the stinkin' mouse!)
    2. Begin typing. Enter "Launching" in the filter box
    3. Open the Launching preferences
    4. In the bottom section, choose "Always launch the previously launched application"
    5. Click OK. Celebrate victory.

    This used to be the default behavior in Eclipse. A while ago, it changed so that it now makes a best guess based on your active resource and editor. That works perfectly . . . until you start doing things more complex. Now the CMD+SHFT+F11 shortcut key runs your last run/debug choice! That alone, will save BOATLOADS of time. Some days, I click "Maven Build" no less than 1 billion times!