Covering J2EE Security and WebLogic Topics

Maven and WebLogicMBeanMaker in WebLogic 9/10

In WebLogicMBeanMaker and Maven I wrote about how to use WebLogicMBeanMaker 8.1 in a Maven 2 build. Even though WebLogicMBeanMaker is documented as a two-step process, the Maven build process allowed us to skip the second step by relying upon Maven’s packaging mechanism. All was well at the time…

Of course, if you have a security provider in WebLogic 8.1 you’re probably going to migrate it to WebLogic 9 or 10 eventually, right? Unfortunately, the old build process is no longer sufficient and you’ll have to make some changes. First, I’ll describe the problem and then show the solution.

Home is where WebLogic is

If you use a POM similar to the one presented in WebLogicMBeanMaker and Maven but with WebLogic 9+ dependencies (note that wlManagement.jar changed to wlManagementMBean.jar in WLS 9), you’ll get the following error:

[java] Compiling inline
[java] WLMaker-SubProcess: : Exception in thread "main" java.lang.ExceptionInInitializerError
[java] WLMaker-SubProcess: :       at java.lang.Class.forName0(Native Method)
[java] WLMaker-SubProcess: :       at java.lang.Class.forName(Class.java:164)
[java] WLMaker-SubProcess: :       at weblogic.management.commo.BeanGenDriver.getManagementTempDir(BeanGenDriver.java:76)
[java] WLMaker-SubProcess: :       at weblogic.management.commo.BeanGenDriver.main(BeanGenDriver.java:118)
[java] WLMaker-SubProcess: : Caused by: java.lang.RuntimeException: error in finding weblogic.Home
[java] WLMaker-SubProcess: :       at weblogic.Home.getInstance(Home.java:90)
[java] WLMaker-SubProcess: :       at weblogic.Home.getPath(Home.java:96)
[java] WLMaker-SubProcess: :       at weblogic.management.bootstrap.BootStrap.init(BootStrap.java:108)
[java] WLMaker-SubProcess: :       at weblogic.management.bootstrap.BootStrap.(BootStrap.java:87)
[java] WLMaker-SubProcess: :       … 4 more
[java] WLMaker-SubProcess: : Stopped draining WLMaker-SubProcess:
[java] BeanGen code generation failed
[java] WLMaker-SubProcess: : Stopped draining WLMaker-SubProcess:

“Error in finding weblogic.Home” is the only thing of value in the exception, but what’s that about? Running setDomainEnv before running Maven didn’t help.

As it turns out, the WebLogic dependencies are location-dependent in some fashion. Simply having weblogic.jar and wlManagementMBean.jar in your Maven repository is not sufficient. While setting a weblogic.home system property has potential, I didn’t have any success with the approach. What did work for me is to use the WebLogic installation directory even though it is less than ideal. Here’s how I configured my dependencies in the POM:

<dependency>
  <groupId>weblogic</groupId>
  <artifactId>weblogic</artifactId>
  <version>9.1.0</version>
  <scope>system</scope>
  <systemPath>C:/bea910/weblogic91/server/lib/weblogic.jar</systemPath>
</dependency>
	
<dependency>
  <groupId>weblogic</groupId>
  <artifactId>wlManagementMBean</artifactId>
  <version>9.1.0</version>
  <scope>system</scope>
  <systemPath>C:/bea910/weblogic91/server/lib/mbeantypes/wlManagementMBean.jar</systemPath>
</dependency>

Essentially, I changed the scope from “provided” to “system” and added the systemPath element which points to the jar in the WebLogic installation directory. I left the hard-coded paths for illustration but you’ll probably want to use properties, instead.

Using the system scope solves the home problem and your provider will build without error. It won’t actually work, but your build was successful so what more could you want? ;-) Seriously, that problem will be solved in the next section, but for completeness, I’d like to point out something in case someone knows a better solution than using a WebLogic installation directory. After all, I’d much rather use the Maven repository and I’m guessing you would, too.

Here’s something I discovered:

If you run

java -classpath C:\bea910\weblogic91\server\lib\weblogic.jar weblogic.Home

you get

C:/bea910/weblogic91/server

If you do the same thing against your repository’s weblogic.jar like this

java -classpath “C:\Documents and Settings\MSF\.m2\repository\weblogic\weblogic\9.1.0\weblogic-9.1.0.jar” weblogic.Home

you get

Exception in thread "main" java.lang.RuntimeException: error in finding weblogic.Home
        at weblogic.Home.getInstance(Home.java:90)
        at weblogic.Home.getHome(Home.java:105)
        at weblogic.Home.main(Home.java:113)

I’m not sure what it means or how to leverage the information but it seems to be the root of the problem. I got tired of messing with it but if you have an idea, please comment.

Moving right along…

Scheming Minds

As I mentioned above, you should now have a JAR file for your provider. If you copy it to the mbeantypes directory and start WebLogic, though, you’ll find that your provider doesn’t show up in WebLogic console. Very annoying, indeed.

As it turns out, our pals at BEA are messing with our heads. Starting with WebLogic 9, you need to dance the MBeanMaker Two-Step because the second phase — which just jarred the provider in the past — now creates schema files among other things. No schema files means no recognition of your provider by WebLogic.

Fortunately, the solution is pretty simple since you just need to run WebLogicMBeanMaker twice to get all of the required artifacts. Here’s my updated POM snippet:

<!-- Run WebLogicMBeanMaker to build the authentication provider -->
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-antrun-plugin</artifactId>
  <executions>
    <execution>
      <id>WebLogicMBeanMaker</id>
      <phase>generate-sources</phase>
      <configuration>
        <tasks>
	
          <echo>Building Authentication provider with WebLogicMBeanMaker...</echo>
	
          <!-- Ensure that WebLogicMBeanMaker starts from a clean slate -->
          <delete dir="${project.build.directory}/generated-sources"/>
	
          <path id="gen.path">
            <pathelement path="${project.build.directory}\generated-sources\main\java"/>
            <path refid="maven.compile.classpath"/>
          </path>
	
          <!-- Copy ZAuthenticator.xml to the generated source directory or it won't work -->
          <copy file="${basedir}/conf/ZAuthenticator.xml" todir="${project.build.directory}/generated-sources/main/java"/> 
	
          <!-- Build the MDF (mbean definition file) for the authenticator -->
          <java classname="weblogic.management.commo.WebLogicMBeanMaker" fork="true" failonerror="true">
            <jvmarg line="-Dfiles=${project.build.directory}/generated-sources/main/java
                          -DMDF=${basedir}/conf/ZAuthenticator.xml
                          -DcreateStubs=true -Dverbose=true "/>
            <classpath>
              <path refid="gen.path"/>
            </classpath>
          </java>
	
          <!-- Build the MJF (mbean jar file) for the authenticator . Also
               generates a set of XML binding classes and a schema. -->
          <java classname="weblogic.management.commo.WebLogicMBeanMaker" fork="true" failonerror="true">
            <jvmarg line="-Dfiles=${project.build.directory}/generated-sources/main/java
                          -DMJF=${basedir}/conf/ZAuthenticator -Dverbose=true "/>
	
            <classpath>
              <path refid="gen.path"/>
            </classpath>
          </java>
	
          <!-- Copy meta-data files to the target/classes directory so they get jarred -->
          <copy todir="${project.build.directory}/classes">
            <fileset dir="${basedir}/conf">
              <include name="**/*.xml"/> <!-- ZAuthenticator.xml -->
              <include name="**/*.dtd"/> <!-- commo.dtd -->
            </fileset>
            <fileset dir="${project.build.directory}/generated-sources/main/java">
              <exclude name="**/*.java"/>
            </fileset>
          </copy>
	
          <echo>Building Authentication provider with WebLogicMBeanMaker. DONE!</echo>
        </tasks>
	
 	  <!-- Add the generated sources to the Maven source directory list -->
        <sourceRoot>${project.build.directory}/generated-sources/main/java</sourceRoot>
      </configuration>
	
      <goals>
        <goal>run</goal>
      </goals>
    </execution>
  </executions>
</plugin>

Now, in addition to the original files, your jar should contain roughly a dozen more files, half of which are XSB files. Your provider should now be recognized by WebLogic after you copy the jar to mbeantypes and restart WebLogic.

Can you handle more good news? The same build configuration works in WebLogic 10.

6 Comments

  1. Thanks for the post and I feel a bit guilty for the problems you are seeing, since I was responsible for WebLogicMBeanMaker tool while I was at BEA. Yes WebLogicMBeanMaker has gone through a lot of change in 9.0 to comply with the new MBean hierarchy model and management API’s. As you have noticed the jar file is a bit bloated, this is because it contains the XSB bindings and schema files that help WebLogic in persisting the security configuration to config.xml (BTW config.xml is schema based). Also, if you are migrating from WLS 8.1 and have a few security providers, you can use the Upgrade tool which may be the best way. See my blog entry at http://dev2dev.bea.com/blog/sghattu/archive/2005/08/upgrading_your.html

    Comment by Satya Ghattu — August 30, 2007 @ 8:29 pm

  2. Satya,

    Thanks for responding. No need for any guilt, though. WebLogicMBeanMaker works just fine until one tries to shoe-horn it into a Maven build. Obviously, even that can be done after learning the tricks.

    What’s funny is that I never actually stopped to ponder what the new schema files were for. Now I know.

    Do you have any insight on the weblogic.Home problem mentioned in the post?

    Are you saying that the upgrade tool would be a viable option for migrating a “living” security provider? I always assumed that the tool was a one-shot deal for when you didn’t have source.

    Thanks,

    Mike

    Comment by Mike Fleming — August 30, 2007 @ 9:27 pm

  3. Mike,
    If I remember correctly the Maker tool uses weblogic.Home.getHome() to get to the BEA installation directory and appends the relative path’s to various different jars it depends on. For instance to get to wlManagment.jar, it will get the installation directory by calling weblogic.Home.getHome() and appends “/server/lib/mbeantypes” to get to the location of wlManagement.jar. As you may have noticed the Maker tool spawns a new JVM couple of times to get some things done and these VM’s needed a special classpath to run. And that is one of the reasons it is slow.
    If you have a 8.1 provider already built using some build mechanisms, I wouldn’t throw it out, because after you build your old provider you can just simply upgrade it using the upgrade tool. The upgrade tool will internally call the MBeanMaker, but I guess you will see this Home issue even then if you are not using weblogic.jar from the installation directory.

    Comment by Satya Ghattu — August 31, 2007 @ 9:14 am

  4. Thanks for the info, Satya.

    Comment by Mike Fleming — August 31, 2007 @ 7:27 pm

  5. Instead of using a WebLogic installation directory, your WL jars that you depend on need to have the same directory structure as the WL install directory. This is due to the fact that weblogic.jar’s manifest has a class-path attribute that depends on other jar files that are likely missing or could not be resolved as the directory structed was incorrect.

    Comment by Doug Harmon — December 29, 2007 @ 7:01 pm

  6. Doug,

    Thanks for the comment. Yes, yours would be a better way but have you figured out how to make that structure work in the Maven repository? That’s what I’d really like to have…

    Comment by Mike Fleming — December 29, 2007 @ 9:52 pm

Sorry, the comment form is closed at this time.

 

Bookmark this page on del.icio.us