Servers

Weblogic Plugin to Set Deployment Order

WebLogic Server 12 has updates to the plugin that allow features such as being able to start/stop servers as well as run WLST scripting. The reason the WLST scripting is a beneficial feature is that the plugin is being used deploy all assets to a target environment (like wars, optional packages, and resources). In deploying all these resources through a build script, it becomes necessary to set the deployment order when assets have a dependency on a resource already being available prior to the asset being started during deployment or start-up of the managed server.

In order to modify the deployment order, a WLST script has to be used because the WebLogic Server 12 plugin does not support setting the deployment order through the maven script. So in order to utilize the newer WebLogic Server 12 maven plugin, it an install of WebLogic Server 12 so that it can utilize the install for running WLST scripts and other functioanility.

In the use case, the servers that exist within the environments is running 11g, however, in order to take advantage of this new feature, the build management system needs access to WebLogic Server 12c. As mentioned previously, this means that WebLogic Server 12 is installed on the build management box (in this case Hudson), so that the Hudson jobs have access to the install for WLST. The tests were ran utilizing the 12c version of the plugin to modify deployment orders on the 11g install and it worked. The only problem with running WLST scripts through Hudson builds is that doing multiple WLST scripts means opening a session with WebLogic Server and then closing that session, multiple times. This overhead is a memory hog and ultimately crashed the Hudson box. So the code/scripting is there to utilize the deployment order, but because of resource constraints, this functionality isn’t currently being used.

The following are the steps I took: 1) Installed WebLogic Server 12c to a local folder WLS_12C_MIDDLEWARE_PATH on the build server 2) Followed all steps from http://docs.oracle.com/cd/E24329_01/web.1211/e24368/maven.htm#CHEFAEBI for apache-maven-2.2.x. 3) Started the target Weblogic server 11g at (11g-IP-addr):7001 4) Edited a project pom.xml for deploying the war:

1
2
</p>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelversion>4.0.0</modelversion> <groupid>com.oracle.test</groupid> <artifactid>sample2</artifactid><packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>sample2 Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupid>junit</groupid> <artifactid>junit</artifactid> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies> <build> <finalname>sample-war</finalname><plugins><plugin> <groupid>org.apache.maven.plugins</groupid> <artifactid>maven-compiler-plugin</artifactid> <configuration> <source>1.6 <target>1.6</target> </configuration> </plugin><plugin> <groupid>com.oracle.weblogic</groupid> <artifactid>wls-maven-plugin</artifactid> <version>12.1.1.0</version> <configuration> <adminurl>t3://(local-IP):7001</adminurl> <user>weblogic</user><password>weblogic1</password> <upload>true</upload> <action>deploy</action> <remote>false</remote> <verbose>true</verbose> <source>target/sample-war-10.war <name>sample-war-10</name> </configuration> <executions> <execution><phase>install</phase> <goals> <goal>deploy</goal> <goal>undeploy</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>

5) Ran a maven command based on the pom for deploying sample-war-10.war:

1
 mvn wls:deploy -DmiddlewareHome=(WLS_12C_MIDDLEWARE_PATH)

I had to use -DmiddlewareHome because the element in pom.xml didn’t work. 6) Created the following WLST script for changing the deployment order (changeOrder.py):

1
2
3
4
5
6
 from java.util import * from javax.management import * import javax.management.Attribute
<p>
    print 'starting the script .... '
</p>
<p>
    connect('weblogic', 'weblogic1', "t3://(11g-IP-addr):7001") edit() startEdit() cd('AppDeployments') cd('sample') set ('DeploymentOrder', 115) save() activate() disconnect() exit()

7) Then incorporated that script within the wls-maven-plugin:

1
2
3
4
5
6
7
</p>
<plugin> <groupid>com.oracle.weblogic</groupid> <artifactid>wls-maven-plugin</artifactid> <executions> <execution><phase>package</phase> <goals> <goal>wlst</goal> </goals> </execution> </executions> <configuration>  from java.util import * from javax.management import * import javax.management.Attribute
<p>
    print 'Updating deployment order .... '
</p>
<p>
    connect(System.getProperty("deploy.user"), System.getProperty("deploy.password"), System.getProperty("deploy.admin")) edit() startEdit() cd(System.getProperty("deploy.mbean")) cd(System.getProperty("deploy.library.name")) set ('DeploymentOrder', System.getProperty("deploy.order")) save() activate() disconnect()

8) Then ran the WLST call from the maven plugin:

1
 mvn wls:wlst -DfileName=changeOrder.py -DmiddlewareHome=(WLS_12C_MIDDLEWARE_PATH)

Properties are fed into the python script from Maven properties (based on a profile which is different for applications, resources, and optional packages).

This is because within the JNDI hierarchy through WLST, these assets get different Types, different versions, and different name. We can see this by logging into the server through a WLST command window and simply running an ls() command on the application or library directory. For instance, the following is an example of running the ls() command on the war. We can see that the type is AppDeployment and that the Identifier and Name are similar.

1
 wls:/sandbox/serverConfig/AppDeployments/sample-war-10> ls() dr--   SubDeployments dr--   Targets -r--   AbsoluteInstallDir                           null -r--   AbsolutePlanDir                              null -r--   AbsolutePlanPath                             null -r--   AbsoluteSourcePath                           /domains/sandbox/servers/sandboxAdminServer/upload/sample-war-10/app/sample-war.war -r--   ApplicationIdentifier                        sample-war-10 -r--   ApplicationName                              sample-war-10 -r--   CompatibilityName                            null -r--   DeploymentOrder                              102 -r--   DeploymentPlan                               null -r--   DeploymentPlanExternalDescriptors            null -r--   DeploymentPrincipalName                      null -r--   InstallDir                                   null -r--   ModuleType                                   war -r--   Name                                         sample-war-10 -r--   Notes                                        null -r--   PlanDir                                      null -r--   PlanPath                                     null -r--   SecurityDDModel                              DDOnly -r--   SourcePath                                   servers/sandboxAdminServer/upload/sample-war-10/app/sample-war.war -r--   StagingMode                                  null -r--   Type                                         AppDeployment -r--   ValidateDDSecurityData                       false -r--   VersionIdentifier                            null -r-x   freezeCurrentValue                           Void : String(attributeName) -r-x   isSet                                        Boolean : String(propertyName) -r-x   unSet                                        Void : String(propertyName)

anabolic steroids for sale

Now we will run the same command, but this time on an Optional Package, like our cxfFull that we created with Apache Shade. We can see here that the type is Library instead of AppDeployment, and that the ApplicationIdentifier includes the Manifest versions identified for this Optional Package. Therefore we need to feed in different properties when attempting to change the deployment order for an application asset as opposed to a library asset.

1
 wls:/sandbox/serverConfig/Libraries/cxfFull#2.4.5@2.4.5> ls() dr--   SubDeployments dr--   Targets -r--   AbsoluteInstallDir                           null -r--   AbsolutePlanDir                              null -r--   AbsolutePlanPath                             null -r--   AbsoluteSourcePath                           /domains/sandbox/servers/sandboxAdminServer/upload/cxfFull/2.4.5@2.4.5/app/cxf-full.jar -r--   ApplicationIdentifier                        cxfFull#2.4.5@2.4.5 -r--   ApplicationName                              cxfFull -r--   CompatibilityName                            null -r--   DeploymentOrder                              95 -r--   DeploymentPlan                               null -r--   DeploymentPlanExternalDescriptors            null -r--   DeploymentPrincipalName                      null -r--   InstallDir                                   null -r--   ModuleType                                   null -r--   Name                                         cxfFull#2.4.5@2.4.5 -r--   Notes                                        null -r--   PlanDir                                      null -r--   PlanPath                                     null -r--   SecurityDDModel                              DDOnly -r--   SourcePath                                   servers/sandboxAdminServer/upload/cxfFull/2.4.5@2.4.5/app/cxf-full.jar -r--   StagingMode                                  null -r--   Type                                         Library -r--   ValidateDDSecurityData                       false -r--   VersionIdentifier                            2.4.5@2.4.5 -r-x   freezeCurrentValue                           Void : String(attributeName) -r-x   isSet                                        Boolean : String(propertyName) -r-x   unSet                                        Void : String(propertyName)

Of course, this can be easily done through the console, but the ability to do it through the usage of the Maven Plugin can speed up the deployment process. One of the ways that we could have sped up the utilization of this plugin would be to open a WLST session, modify the deployment order of all the assets we were deploying and then closed the WLST session. Instead of trying to open, modify, close a session for each asset that was being deployed.

Top Downloaded Mp3s

Share and Enjoy

Hibernate and JPA 2.0 with WebLogic Server

I talked a little about utilizing Hibernate/JPA 2 with WebLogic Server in my blog about (Multiple persistence.xml files and JPA). First off, the idea was to utilize JPA 2 and use Hibernate as the provider so that all the persistence logic could be written against JPA. Long-term, this was a mistake, since Hibernate has such advanced features such as their Filters and Interceptors that Hibernate’s API began to slowly creep into the core persistence classes we developed. So even though the initial concept seemed ideal to have this separation where the persistence provider would be hidden from application logic, that quickly changed and it became apparent that much time and effort would have been saved in just using Hibernate as opposed to coupling it with JPA 2.

That being said, in order to get Hibernate to work in WebLogic Server, one of the simplest things to do is create a preclasspath directory that we can place in front of WebLogic libraries in the WebLogic Server startup script. Then additional libraries can be added to this folder that are necessary to implement features where library collisions occur with WebLogic Server weblogic.jar and other default jars (such as saaj-impl.jar). Since the weblogic.jar contains many 3rd party libraries, and older versions than we like to use, we have to place the antlr jar in this preclasspath directory (along with other ones such as commons-lang.jar and saaj-impl.jar). Once we start our WebLogic Server, we start getting errors related to this Oracle Forum post (Thread: Hibernate 3.6 Final (JPA 2.0) + WL 10.3.x :Unable to deploy sample appn) and Can not deploy 3.5 to Weblogic 10.3 server. The error is basically:

1
java.lang.Throwable: java.lang.NoSuchMethodError: javax.persistence.spi.PersistenceUnitInfo.getValidationMode()Ljavax/persistence/ValidationMode;

The way to simply resolve this is by putting the “hibernate-jpa-2.0-api-1.0.1.Final.jar” into the preclasspath folder in WebLogic Server and restart the server. This appeared to fix the issue, until we actually started doing testing later on in other environments related to the Validation Framework. The following error began to appear (ignore the jar names, I use Apache Shade to combine the multiple hibernate jars into a single jar):

1
2
3
4
5
6
7
8
9
10
11
java.lang.AbstractMethodError: null        
at javax.persistence.Persistence$1.isLoaded(Persistence.java:93) ~[hibernate-jpa-2.0-api-1.0.1.Final.jar:1.0.1.Final]        
at org.hibernate.validator.engine.resolver.JPATraversableResolver.isReachable(JPATraversableResolver.java:61) ~[hibernate-full.jar:3.6.9]        
at org.hibernate.validator.engine.resolver.DefaultTraversableResolver.isReachable(DefaultTraversableResolver.java:131) ~[hibernate-full.jar:3.6.9]        
at org.hibernate.validator.engine.resolver.SingleThreadCachedTraversableResolver.isReachable(SingleThreadCachedTraversableResolver.java:46) ~[hibernate-full.jar:3.6.9]
at org.hibernate.validator.engine.ValidatorImpl.isValidationRequired(ValidatorImpl.java:1242) ~[hibernate-full.jar:3.6.9]        
at org.hibernate.validator.engine.ValidatorImpl.validateConstraint(ValidatorImpl.java:448) ~[hibernate-full.jar:3.6.9]        
at org.hibernate.validator.engine.ValidatorImpl.validateConstraintsForDefaultGroup(ValidatorImpl.java:397) ~[hibernate-full.jar:3.6.9]        
at org.hibernate.validator.engine.ValidatorImpl.validateConstraintsForCurrentGroup(ValidatorImpl.java:361) ~[hibernate-full.jar:3.6.9]        
at org.hibernate.validator.engine.ValidatorImpl.validateInContext(ValidatorImpl.java:313) ~[hibernate-full.jar:3.6.9]        
at org.hibernate.validator.engine.ValidatorImpl.validate(ValidatorImpl.java:139) ~[hibernate-full.jar:3.6.9]

The next step was to upgrade the Hibernate Validator framework jars and also attempt to upgrade the Hibernate jars, but this did not seem to alleviate our issues. Plus, the phase of the project did not allow the upgrade from a Hibernate 3.6.0 to the newer Hibernate 4.* without some serious regression. So with some additional research, the issue seemed to really resolve around what implementation classes were being forced down the WebLogic Server classpath, as opposed to the libraries that were being supplied within the WAR. The following two links were discussions that related to this issue:

@Valid annotation gives java.lang.AbstractMethodError
AbstractMethodError in WebLogic 10.3.4
Validator fails when a non-Hibernate persistence layer is in the classpath

So through these discussions as well as a few other threads that I cannot seem to find now, the resolution was to get rid of the preclasspath library of hibernate-jpa-2.0-api-1.0.1.Final.jar and replace that jar with another spec reference from Geronimo called geronimo-jpa_2.0_spec-1.1.jar. With this replacement, the JPA 2.0 functionality continued to work because of the provided interfaces within the Geronimo API, and the AbstractMethodError disappeared when utilizing the Validator Framework functionality.

Share and Enjoy

WebLogic Password Decryption

In a previous blog post (WebLogic Encryption and Domains), I talked about how we can store the Salt files inside a Maven Project and be able to generate encrypted passwords that will be used on the server.

We can use that same project, and the code from this resource to allow the same project to decrypt passwords. This has been necessary when a password appears to get out of sync with another environment, and we can decrypt the password to verify what it was set to.

http://jagadesh4java.blogspot.com/2012/07/weblogic-password-decrypt.html

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
import weblogic.security.internal.SerializedSystemIni;
import weblogic.security.internal.ServerAuthenticate;
import weblogic.security.internal.encryption.ClearOrEncryptedService;
import weblogic.security.internal.encryption.EncryptionService;

public class Decrypt {
    static EncryptionService es = null;
    static ClearOrEncryptedService ces = null;

    public static void main(String args[]) {
        String s = null;
        if (args.length == 0) {
            s = ServerAuthenticate.promptValue("Password to decrypt: ", false);
        } else if (args.length == 1) {
            s = args[0];
        } else {
            System.err.println("Usage: java Decrypt [ password ]");
        }
        es = SerializedSystemIni.getExistingEncryptionService();
        if (es == null) {
            System.err.println("Unable to initialize encryption service");
            return;
        }
        ces = new ClearOrEncryptedService(es);
        if (s != null) {
            System.out.println("\nDecrypted Password is:" + ces.decrypt(s));
        }
    }
}

We can then add a profile for decrypt and add one for encrypt (which will be activated by default):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<profiles>
   <profile>
       <id>encrypt</id>
       <activation>
           <activeByDefault>true</activeByDefault>
        </activation>
       <properties>
           <security.name>Encryption</security.name>
           <security.class>weblogic.security.Encrypt</security.class>
       </properties>
   </profile>
   <profile>
       <id>decrypt</id>
       <properties>
           <security.name>Decryption</security.name>
           <security.class>com.foo.Decrypt</security.class>
       </properties>
   </profile>
</profiles>

And now we can just run a command of “mvn exec:exec -Pdecrypt” and we will be prompted to enter an encrypted password. I decrypted password will be returned to the console.

Share and Enjoy