Friday, June 27, 2014

Signing JAR File

You use the JAR Signing and Verification Tool to sign JAR files and time stamp the signature. You invoke the JAR Signing and Verification Tool by using the jarsignercommand, so we'll refer to it as "Jarsigner" for short.
To sign a JAR file, you must first have a private key. Private keys and their associated public-key certificates are stored in password-protected databases called keystores. A keystore can hold the keys of many potential signers. Each key in the keystore can be identified by an alias which is typically the name of the signer who owns the key. The key belonging to Rita Jones might have the alias "rita", for example.
The basic form of the command for signing a JAR file is
jarsigner jar-file alias
In this command:
  • jar-file is the pathname of the JAR file that's to be signed.
  • alias is the alias identifying the private key that's to be used to sign the JAR file, and the key's associated certificate.
The Jarsigner tool will prompt you for the passwords for the keystore and alias.
This basic form of the command assumes that the keystore to be used is in a file named .keystore in your home directory. It will create signature and signature block files with names x.SF and x.DSA respectively, where x is the first eight letters of the alias, all converted to upper case. This basic command will overwrite the original JAR file with the signed JAR file.
In practice, you might want to use one or more of the command options that are available. For example, time stamping the signature is encouraged so that any tool used to deploy your application can verify that the certificate used to sign the JAR file was valid at the time that the file was signed. A warning is issued by the Jarsigner tool if a time stamp is not included.
Options precede the jar-file pathname. The following table describes the options that are available:

Jarsigner Command Options
OptionDescription
-keystore urlSpecifies a keystore to be used if you don't want to use the .keystore default database.
-storepass passwordAllows you to enter the keystore's password on the command line rather than be prompted for it.
-keypass passwordAllows you to enter your alias's password on the command line rather than be prompted for it.
-sigfile fileSpecifies the base name for the .SF and .DSA files if you don't want the base name to be taken from your alias. file must be composed only of upper case letters (A-Z), numerals (0-9), hyphen (-), and underscore (_).
-signedjar fileSpecifies the name of the signed JAR file to be generated if you don't want the original unsigned file to be overwritten with the signed file.
-tsa urlGenerates a time stamp for the signature using the Time Stamping Authority (TSA) identified by the URL.
-tsacert aliasGenerates a time stamp for the signature using the TSA's public key certificate identified by alias.
-altsigner classIndicates that an alternative signing mechanism be used to time stamp the signature. The fully-qualified class name identifies the class used.
-altsignerpath classpathlistProvides the path to the class identified by the altsigner option and any JAR files that the class depends on.

Example

Let's look at a couple of examples of signing a JAR file with the Jarsigner tool. In these examples we will assume:
  • your alias is "johndoe".
  • the keystore you want to use is in a file named "mykeys" in the current working directory.
  • the keystore's password is "abc123".
  • the TSA that you want to use to time stamp the signature is located at http://example.tsa.url
Under these assumptions, you could use this command to sign a JAR file named app.jar:
jarsigner -keystore mykeys -storepass abc123 -tsa http://example.tsa.url app.jar johndoe
You will be prompted for the keystore password. Because this command doesn't make use of the -sigfile option, the .SF and .DSA files it creates would be namedJOHNDOE.SF and JOHNDOE.DSA. Because the command doesn't use the -signedjar option, the resulting signed file will overwrite the original version of app.jar.
Let's look at what would happen if you used a different combination of options:
jarsigner -keystore mykeys -sigfile SIG -signedjar SignedApp.jar 
-tsacert testalias app.jar johndoe
This time, you would be prompted to enter the passwords for both the keystore and your alias because the passwords aren't specified on the command line. The signature and signature block files would be named SIG.SF and SIG.DSA, respectively, and the signed JAR file SignedApp.jar would be placed in the current directory. The original unsigned JAR file would remain unchanged. Also, the signature would be time stamped with the TSA's public key certificate identified as testalias.

Additional Information

Complete reference pages for the JAR Signing and Verification Tool are on-line: Summary of Security Tools

Extracting the Contents of a JAR File

The basic command to use for extracting the contents of a JAR file is:
jar xf jar-file [archived-file(s)]
Let's look at the options and arguments in this command:
  • The x option indicates that you want to extract files from the JAR archive.
  • The f options indicates that the JAR file from which files are to be extracted is specified on the command line, rather than through stdin.
  • The jar-file argument is the filename (or path and filename) of the JAR file from which to extract files.
  • archived-file(s) is an optional argument consisting of a space-separated list of the files to be extracted from the archive. If this argument is not present, the Jar tool will extract all the files in the archive.
As usual, the order in which the x and f options appear in the command doesn't matter, but there must not be a space between them.
When extracting files, the Jar tool makes copies of the desired files and writes them to the current directory, reproducing the directory structure that the files have in the archive. The original JAR file remains unchanged.

Caution: When it extracts files, the Jar tool will overwrite any existing files having the same pathname as the extracted files.

An Example

Let's extract some files from the TicTacToe JAR file we've been using in previous sections. Recall that the contents of TicTacToe.jar are:
META-INF/MANIFEST.MF
TicTacToe.class
TicTacToe.class
TicTacToe.java
audio/
audio/beep.au
audio/ding.au
audio/return.au
audio/yahoo1.au
audio/yahoo2.au
example1.html
images/
images/cross.gif
images/not.gif
Suppose you want to extract the TicTacToe class file and the cross.gif image file. To do so, you can use this command:
jar xf TicTacToe.jar TicTacToe.class images/cross.gif
This command does two things:
  • It places a copy of TicTacToe.class in the current directory.
  • It creates the directory images, if it doesn't already exist, and places a copy of cross.gif within it.
The original TicTacToe JAR file remains unchanged.
As many files as desired can be extracted from the JAR file in the same way. When the command doesn't specify which files to extract, the Jar tool extracts all files in the archive. For example, you can extract all the files in the TicTacToe archive by using this command:
jar xf TicTacToe.jar

Spring, JMX & Weblogic Server

I assume you have heard of Java’s JMX features and familiar what it does (expose and manage your service remotely). You ought to know that default JVM will have a Platform MBeanServer instance that you can register MBean. And you may view them using the jconsole command from the JDK.

As of today, I think by far the easiest way you can expose any services in your application to a JMX MBeanServer is using Spring’s exporter. You will do something like this:

<bean class="org.springframework.jmx.export.MBeanExporter">
<property name="assembler">
 <bean class="org.springframework.jmx.export.assembler.InterfaceBasedMBeanInfoAssembler">
<property name="managedInterfaces">
<list>
<!-- Expose any java interface you like to see under JMX as MBean -->
<value>myproject.services.Service</value>
</list>
</property>
 </bean>
</property>
<property name="beans">
 <map>
<entry key="myproject.services:name=MyCoolService" value-ref="myCoolService"/>
 </map>
</property>
</bean>
<!-- This service must implements the interface used above -->
<bean id="myCoolService" class="myproject.services.MyCoolService">
</bean>
= = = = = = Example : implementation in one project = = = = = = =
<!-- MBEAN CONFIGURATIONS -->
<bean id="MBeanExporter" class="org.springframework.jmx.export.MBeanExporter" lazy-init="false">
<property name="beans">
<map>
<entry key="Eep:service=EventPublication, name=PerformanceMonitor, version=${release.number}" value-ref="PerformanceAspect"/>
</map>
</property>
<property name="server">
 <bean class="org.springframework.jndi.JndiObjectFactoryBean">
  <property name="jndiName" value="java:comp/jmx/runtime"/>
</bean>
</property>
<property name="assembler">
<bean class="org.springframework.jmx.export.assembler.InterfaceBasedMBeanInfoAssembler">
<property name="interfaceMappings">
<props>
                                    <prop key="Eep:service=EventPublication, name=PerformanceMonitor, version=${release.number}">                       
                                                     com.comcast.core.framework.performance.ManagablePerformanceMonitor
                                            </prop>
</props>
</property>
</bean>
</property>
<property name="registrationBehaviorName" value="REGISTRATION_REPLACE_EXISTING"/>

</bean>
= = = = = = = = = = = = =

Above should get you standalone application with JMX enabled. Now if you want to do similar on WebLogic Server, then I have few goodies and notes that might help you. Read on…

WebLogic Server’s (WLS) MBeanServer

The JConsole trick: The WLS, like many other EE server will have it’s own MBeanServer. However, to see the MBean’s you would need to do little extra with jconsole. Assume you have a default config WLS started on localhost, then you can connect to it like this.
$ jconsole -J-Djava.class.path="$JAVA_HOME/lib/jconsole.jar:$MW_HOME/wlserver/server/lib/wljmxclient.jar" -J-Djmx.remote.protocol.provider.pkgs=weblogic.management.remote
Then when prompted to login, enter the following:
Remote Process: service:jmx:iiop://localhost:7001/jndi/weblogic.management.mbeanservers.runtime
User: <same userid you used setup WLS to their console app.>
Password: <same password you used setup WLS to their console app.>
Now you should see all the MBeans that WLS already exposed to you as a EE server. You may add your own service there.

Programming with JMX connectionYou may connect to the WLS MBeanServer remotely inside your standalone application. Here is a typical connection code you would need
String serviceName= "com.bea:Name=DomainRuntimeService,Type=weblogic.management.mbeanservers.domainruntime.DomainRuntimeServiceMBean";
try {
ObjectName service = new ObjectName(serviceName);
} catch (MalformedObjectNameException e) {
throw new RuntimeException("Not able to create JMX ObjectName: " + serviceName);
}

String protocol = "t3";
String jndiroot = "/jndi/";
String mserver = "weblogic.management.mbeanservers.runtime";
try {
JMXServiceURL serviceURL = new JMXServiceURL(protocol, "localhost", 7001, jndiroot + mserver);

Hashtable h = new Hashtable();
h.put(Context.SECURITY_PRINCIPAL, username);
h.put(Context.SECURITY_CREDENTIALS, password);
h.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES,"weblogic.management.remote");
h.put("jmx.remote.x.request.waiting.timeout", new Long(10000));
JMXConnector connector = JMXConnectorFactory.connect(serviceURL, h);
MBeanServerConnection remoteMBeanServer = connector.getMBeanServerConnection();

// TODO: Do what you need with remoteMBeanServer here.
} catch (Exception e) {
throw new RuntimeException("Not able to initiate MBeanServer protocol= " + protocol +", jndiroot= " + jndiroot + ", mserver= " + mserver);
}
That’s a mouthful of boiler code just to get a remote MBeanServer connection! Fortunately there is another easier way though. Read on…

The JNDI trick: The WLS MBeanServer service is also available through JNDI lookup. Again Spring can help you with their JNDI lookup and you simply need to inject it to other services that need it. For example:
    <bean id="jmxServerRuntime" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiName" value="java:comp/env/jmx/runtime"/>
    </bean>
    <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
        <property name="beans">
            <map>
                <entry key="myproject.services:name=MyCoolService" value-ref="myCoolService"/>
            </map>
        </property>
        <property name="server" ref="jmxServerRuntime"/>
    </bean>
Notice that we have injetcted the "server" property with one we looked up from WLS JNDI service. If you use that in your WAR application and deploy it onto a WLS instance, and whola, you got yourself exposed service onto WLS JMX!

NOTE
above will only works if your Spring xml config is part of the WAR/JAR/EAR that’s deployed in same server where JNDI lives! If you are not, you need to use this JNDI name without the "env" part instead, like "java:comp/env/jmx/runtime".

JMX References: Spring 3,

Running JAR-Packaged Software

Now that you have learned how to create JAR files, how do you actually run the code you packaged? Consider these scenarios:
  • Your JAR file contains an applet that is to be run inside a browser.
  • Your JAR file contains an application that is to be started from the command line.
  • Your JAR file contains code that you want to use as an extension.
This section will cover the first two situations. A separate trail in the tutorial on the extension mechanism covers the use of JAR files as extensions.

Applets Packaged in JAR Files

To start any applet from an HTML file for running inside a browser, you use the applet tag. For more information, see the Java Applets lesson. If the applet is bundled as a JAR file, the only thing you need to do differently is to use the archive parameter to specify the relative path to the JAR file.
As an example, use the TicTacToe demo applet. The applet tag in the HTML file that displays the applet can be marked up like this:
<applet code=TicTacToe.class 
width="120" height="120">
</applet>
If the TicTacToe demo was packaged in a JAR file named TicTacToe.jar, you can modify the applet tag with the addition of an archive parameter:
<applet code=TicTacToe.class 
archive="TicTacToe.jar"
width="120" height="120">
</applet>
The archive parameter specifies the relative path to the JAR file that contains TicTacToe.class. For this example it is assumed that the JAR file and the HTML file are in the same directory. If they are not, you must include the JAR file's relative path in the archive parameter's value. For example, if the JAR file was one directory below the HTML file in a directory called applets, the applet tag would look like this:
<applet code=TicTacToe.class 
archive="applets/TicTacToe.jar"
width="120" height="120">
</applet>

JAR Files as Applications

You can run JAR packaged applications with the Java launcher (java command). The basic command is:
java -jar jar-file
The -jar flag tells the launcher that the application is packaged in the JAR file format. You can only specify one JAR file, which must contain all of the application-specific code.
Before you execute this command, make sure that the runtime environment has information about which class within the JAR file is the application's entry point.
To indicate which class is the application's entry point, you must add a Main-Class header to the JAR file's manifest. The header takes the form:
Main-Class: classname
The header's value, classname, is the name of the class that is the application's entry point.
For more information, see the Setting an Application's Entry Point section.
When the Main-Class is set in the manifest file, you can run the application from the command line:
java -jar app.jar
To run the application from the jar file that is in another directory, you must specify the path of that directory: java -jar path/app.jar

Weblogic Singleton Service

WebLogic Server has supported the notion of a Singleton Service for a number of releases, in which WebLogic Server will maintain a single instance of a configured singleton service on one managed server within a cluster.  The singleton can be migrated to another server in the cluster, either automatically if it's current hosting server becomes available, or manually at an operators request.  The singleton can be optionally be configured with a preferred server to run on, as well as a set of named servers to which it can be migrated.  A singleton can be deployed as a standalone service or as part of an application deployment.

With this capability, a question arises from time-to-time whether the Singleton Service feature in WebLogic Server can be used to provide a cluster wide singleton service for applications to use. The answer to this is yes, but it requires you to do a few things to expose the singleton instance to applications running in the cluster so that it can be looked up and used.

Since a singleton service is basically a POJO that implements the weblogic.cluster.singleton.SingletonService interface, which gets instantiated and managed by WebLogic Server, it doesn't have a surface area that allows it to be seen by applications running in the cluster.

To allow the singleton service to be used by applications, in addition to implementing the basic logic that is required, it also needs to perform the following tasks: 
Provide an RMI Remote interface that the singleton service additionally implements, which then allows it to be accessed and invoked from any server in the cluster
When the singleton service is activated, it binds itself into the cluster-wide JNDI tree
 When the singleton service is deactivated, unbinds itself from the cluster-wide JNDI tree

package sab.demo.wlssingletoninstance;

import java.rmi.Remote;
import java.rmi.RemoteException;
public interface DemoSingleton extends Remote {    
    public final String JNDI_NAME="DemoSingleton";
    public String singletonLocation();
    public String getWebLogicServerName();
    public String getHostName();
    public int increment();
    public int value();
}

package sab.demo.wlssingletoninstance;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.rmi.RemoteException;
import java.util.logging.Logger;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
import weblogic.cluster.singleton.SingletonService;
import weblogic.jndi.Environment;

/**
 * Example of a WebLogic Server Singleton Service that can be accessed from
 * other deployed components.
 */
public class DemoSingletonImpl implements DemoSingleton, SingletonService {
    private Integer counter = 0;
    final private Logger logger = new Logger().getLogger("DemoSingletonImpl");
    public DemoSingletonImpl() {
        super();
        logger.info("Constructor");
    }
    // ===================== Singleton Service Methods ================ //
    
    @Override
    public void activate() {
        logger.info("Activate on " + singletonLocation());
        counter = 0;
        try {
            Environment env = new Environment();
            Context ctx = env.getInitialContext();
            ctx.rebind(JNDI_NAME, this);
            logger.info("Executed bind for: " + JNDI_NAME);
            logger.info(String.format("Looking up JNDI_NAME returns: %s", ctx.lookup(JNDI_NAME).getClass().getName()));
            //quickTest();

        } catch (NamingException e) {
            logger.warning("Unable to bind: " + this.getClass().getName() + " into JNDI as:" + this.getClass().getName() + ", Error: " + e.getMessage());
        }
    }

    @Override
    public void deactivate() {
        logger.info("Deactivate on " + singletonLocation());
        try {
            Environment env = new Environment();
            Context ctx = env.getInitialContext();
            ctx.unbind(JNDI_NAME);
            logger.info("Executed unbind for: " + JNDI_NAME);
        } catch (NamingException e) {
            System.out.println("\tUnable to unbind from JNDI as: " + JNDI_NAME + ", Error: " + e.getMessage());
        }
    }
    // ========================= Remotable Methods ==================== //
    
    @Override
    public String singletonLocation()  {
        return String.format("%s %s",
                getHostName(),
                getWebLogicServerName());
    }

    @Override
    public String getWebLogicServerName() {
        return Utilities.getWebLogicServerName();
    }

    @Override
    public String getHostName() {
        return Utilities.getHostName();
    }

    @Override
    public synchronized int increment() {
        counter++;
        return counter.intValue();
    }

    @Override
    public int value() {
        return counter.intValue();
    }

    // ========================== Private Methods ===================== //
    
    /**
     * Called on activate to verify binding is available
     */
    private void quickTest() {
        try {
            Environment env = new Environment();
            Context ctx = env.getContext();
            DemoSingleton singleton = (DemoSingleton) PortableRemoteObject.narrow(ctx.lookup(DemoSingleton.JNDI_NAME), DemoSingleton.class);
            logger.info("quickTest: " + singleton.singletonLocation());
        } catch (Exception ne) {
            logger.log(Logger.SEVERE, ne);
            logger.severe("Error: %s" + ne.getMessage());
        }
    }
}

Deploying and Configuring the Singleton: To deploy the singleton in standalone mode, compile and package the classes into a JAR file and put the JAR file into the WebLogic Server classpath. Note this needs to be done on each physical machine where the managed servers in the cluster run.

You configure a singleton service instance for cluster using the WebLogic Server console [one can also configure same in deployment metadata file].
This ultimately writes an entry in the domain's config.xml as such:
<singleton-service>
  <name>DemoSingleton</name>
  <user-preferred-server>Mike</user-preferred-server>
  <class-name>sab.demo.wlssingletoninstance.DemoSingletonImpl</class-name>
  <cluster>Tingles</cluster>
</singleton-service>
When the preferred managed server starts, the singleton service will be instantiated. 

Applications wishing to use the singleton service then need to look it up from the cluster-wide JNDI tree, narrow it to singleton service type and invoke it's methods as needed.

  private DemoSingleton getSingleton() throws ClassCastException, NamingException {
    Context ctx = getInitialContext()
    DemoSingleton singleton = (DemoSingleton) PortableRemoteObject.narrow(ctx.lookup(DemoSingleton.JNDI_NAME), DemoSingleton.class);
    return singleton;
}

When the singleton service is migrated, the servlet then seamlessly accesses it on the other managed server, where it is now co-located in this specific example below.

WebLogic's SerializedSystemIni.dat

I once encountered a peculiar problem with WebLogic's SerializedSystemIni.dat file. Upon restarting a WebLogic admin or managed server, we would encounter an exception like:
<1/06/2009 02:23:35 PM EST> <Warning> <Security> <BEA-090066> <Problem handling boot identity. The following exception was generated: weblogic.security.internal.SerializedSystemIniException: [Security:090208]Corrupt SerializedSystemIni.dat>
<1/06/2009 02:23:35 PM EST> <Info> <Security> <BEA-090065> <Getting boot identity from user.>
Enter username to boot WebLogic server:

We quickly noticed that the SerializedSystemIni.dat file was 0 bytes in size, the problem occurred again sometime later in a restricted test environment. This time we knew it was a WebLogic quirk of some sort.

SerializedSystemIni.dat Explained: If you've ever looked through config.xml, you may have noticed password values that look like "{3DES}bOH6MEd8S82sxg2Nk=". This is how WebLogic stores passwords encrypted with the "Triple DES" algorithm(3DES).

When WebLogic stores or retrieves one of these passwords, it uses a hash key which is stored in the SerializedSystemIni.dat file.  That's right, the key to all your encrypted admin and DB passwords is right there on your file system. Read access is all that is needed to compromise a WebLogic domain. Perhaps worse, you could be making DB passwords available.

If you're wondering where this file is located, its in the domain directory for WebLogic 8 (or earlier) and in the 'security' directory for WebLogic 9 or later.

Solving the 0-Byte SerializedSystemIni.dat Problem: It wasn't until I understood the purpose of this file that I was able to solve the 0-byte problem. Some time after we noticed SerializedSystemIni.dat was being corrupted, we realized the problem was occurring after the server had run out of disk space.

After a lot of googling and well-intended but limited help from BEA, we discovered that SerializedSystemIni.dat is periodically re-written by the WebLogic Admin server. If the server is unable to write the contents of the file (disk is full, etc), WebLogic will lose the hash key and will no longer be able to decrypt any passwords. I.e. if you're the admin, you'd better have backups or personal indemnity insurance.

So if you are wondering why your WebLogic servers won't start, and SerializedSystemIni.dat is 0 bytes in size, you now know why. The solution? Don't let your server's disk fill up.

I explained that the SerializedSystemIni.dat file in WebLogic contains the key used to encrypt and decrypt passwords. If you're not currently keeping this file secure I suggest you do, as with it someone can (to name a few things):

  • Decrypt the WebLogic admin username and password from boot.properties.
  • Recover database passwords, if JDBC Connection pools are configured, from config.xml.
  • Recover the keystore passwords from config.xml and obtain SSL certificates stored in the jks keystores.
Essentially, they can do whatever they want, so if you don't know who can read your SerializedSystemIni.dat files, look... now.
In this article I will show how easy it is for this file to be used to recover lost passwords via a simple WLST script.
The Script
The script I use to decrypt passwords is incredibly short, and it works with WebLogic 8, 9 and 10 (probably for version 7 too). To use it, just create a new file called decryptpwd.py and paste the following code into it:
 = = = = = = = = = = = = = = = = =

from weblogic.security.internal import *
from weblogic.security.internal.encryption import *

# Remind user about how to use
raw_input("Please ensure SerializedSystemIni.dat is in the current directory now, and press ENTER to continue.")

# Get encryption service
encryptionService = SerializedSystemIni.getEncryptionService(".")
clearOrEncryptService = ClearOrEncryptedService(encryptionService)

# Get user to enter password
pwd = raw_input("Enter encrypted password (Eg. {3DES}Y1fA34S...): ")

# Remove unnecessary escape characters
preppwd = pwd.replace("\\", "")

# Decrypt the password
print "Recovered password is: " + clearOrEncryptService.decrypt(preppwd)
= = = = = = = = = = = = = = = = 
Running the Script:
To run this script, execute the WLST environment and provide it with the script to run. If you're using a version of WebLogic older than 8.1.6 you'll need to install a newer version which has WLST.
Use the following command (replace %WL_HOME% with the correct directory) to run the script.
%WL_HOME%\common\bin\wlst.cmd decryptpwd.py

Once the WLST environment has started up, the script will remind you to copy the SerializedSystemIni.dat file into the current directory. Press enter and paste your encrypted password string. That's it. It will spit out the password in plain-text.
Understanding the Script:
The script is so short and simple it is barely worth explaining, but here are a few things worth mentioning.
You'll notice that the first two lines import weblogic.security packages. These are largely undocumented, so don't expect to find much information on them.
The next significant piece of code instantiates a ClearOrEncryptedService object which will use the SerializedSystemIni.dat file located in the current directory (".").
The final line of code decrypts the password and prints it in plain text.
= = = = = = = = = = = = = = = =

How to decrypt WebLogic passwords with WLST

Sooner or later you will find the situation where you do not remember any of the WebLogic Server password’s stored in the configuration files.

Some examples are:
  1. The WebLogic Server administrator credentials (username and password) stored in the files config.xml and boot.properties
  2. Node Manager password, stored also in the config.xml file (if you still have the default password, don’t wait and change it know!!)
  3. Database password used by the JDBC Data Sources and stored in the file [DOMAIN_HOME]/config/jdbc/[datasource_name].xml
So, how to decrypt this data in 3 easy steps. Just follow this techtapa recipe:
Ingredients:
- 1 WLST script
- The path of the WebLogic Server domain
- The encrypted field, for example, username and password from boot.properties
import os
import weblogic.security.internal.SerializedSystemIni
import weblogic.security.internal.encryption.ClearOrEncryptedService

def decrypt(domainHomeName, encryptedPwd):
    domainHomeAbsolutePath = os.path.abspath(domainHomeName)
    encryptionService = weblogic.security.internal.SerializedSystemIni.getEncryptionService(domainHomeAbsolutePath)
    ces = weblogic.security.internal.encryption.ClearOrEncryptedService(encryptionService)
    clear = ces.decrypt(encryptedPwd)
    print "RESULT:" + clear

try:
    if len(sys.argv) == 3:
        decrypt(sys.argv[1], sys.argv[2])
    else:
  print "INVALID ARGUMENTS"
  print " Usage: java weblogic.WLST decryptPassword.py DOMAIN_HOME ENCRYPTED_PASSWORD"
  print " Example:"
  print " java weblogic.WLST decryptPassword.py D:/Oracle/Middleware/user_projects/domains/base_domain {AES}819R5h3JUS9fAcPmF58p9Wb3syTJxFl0t8NInD/ykkE="
except:
    print "Unexpected error: ", sys.exc_info()[0]
    dumpStack()
    raise

2. Set your environment (CLASSPATH, PATH,..). Open a console, go to [FMW_HOME]/wlserver_10.3/server/bin/ and run the script setWLSEnv.sh:
$ . ./setWLSEnv.sh

3.Run the script. Go to the path where you copied the WLST script ( decryptPassword.py) and run it. You must provide two arguments, the WebLogic Server domain Home full path and the string you want to decrypt, for example:
$ java weblogic.WLST decryptPassword.py /opt/oracle/Middleware/user_projects/domains/base_domain {AES}LU5dLPP0PliNb5Ml1Fo7rD2AbNFwLcyLtYUEDTb+8zY\=



Understanding the Default Manifesh

When you create a JAR file, it automatically receives a default manifest file. There can be only one manifest file in an archive, and it always has the pathname
META-INF/MANIFEST.MF
When you create a JAR file, the default manifest file simply contains the following:
Manifest-Version: 1.0
Created-By: 1.7.0_06 (Oracle Corporation)
These lines show that a manifest's entries take the form of "header: value" pairs. The name of a header is separated from its value by a colon. The default manifest conforms to version 1.0 of the manifest specification and was created by the 1.7.0_06 version of the JDK.
The manifest can also contain information about the other files that are packaged in the archive. Exactly what file information should be recorded in the manifest depends on how you intend to use the JAR file. The default manifest makes no assumptions about what information it should record about other files.

Setting Package Version Information

You may need to include package version information in a JAR file's manifest. You provide this information with the following headers in the manifest:
Headers in a manifest
HeaderDefinition
NameThe name of the specification.
Specification-TitleThe title of the specification.
Specification-VersionThe version of the specification.
Specification-VendorThe vendor of the specification.
Implementation-TitleThe title of the implementation.
Implementation-VersionThe build number of the implementation.
Implementation-VendorThe vendor of the implementation.
One set of such headers can be assigned to each package. The versioning headers should appear directly beneath the Name header for the package. This example shows all the versioning headers:
Name: java/util/
Specification-Title: Java Utility Classes
Specification-Version: 1.2
Specification-Vendor: Example Tech, Inc.
Implementation-Title: java.util
Implementation-Version: build57
Implementation-Vendor: Example Tech, Inc.
For more information about package version headers, see the Package Versioning specification .

An Example

We want to include the headers in the example above in the manifest of MyJar.jar.
We first create a text file named Manifest.txt with the following contents:
Name: java/util/
Specification-Title: Java Utility Classes
Specification-Version: 1.2
Specification-Vendor: Example Tech, Inc.
Implementation-Title: java.util
Implementation-Version: build57
Implementation-Vendor: Example Tech, Inc.

Warning: The text file must end with a new line or carriage return. The last line will not be parsed properly if it does not end with a new line or carriage return.
We then create a JAR file named MyJar.jar by entering the following command:
jar cfm MyJar.jar Manifest.txt MyPackage/*.class
This creates the JAR file with a manifest with the following contents:
Manifest-Version: 1.0
Created-By: 1.7.0_06 (Oracle Corporation)
Name: java/util/
Specification-Title: Java Utility Classes
Specification-Version: 1.2
Specification-Vendor: Example Tech, Inc.
Implementation-Title: java.util
Implementation-Version: build57
Implementation-Vendor: Example Tech, Inc.

The JarRunner Class

The JarRunner application is launched with a command of this form:
java JarRunner url [arguments]
In the previous section, we've seen how JarClassLoader is able to identify and load the main class of a JAR-bundled application from a given URL. To complete the JarRunner application, therefore, we need to be able to take a URL and any arguments from the command line, and pass them to an instance of JarClassLoader. These tasks belong to the JarRunner class, the entry point of the JarRunner application.
It begins by creating a java.net.URL object from the URL specified on the command line:
public static void main(String[] args) {
if (args.length < 1) {
usage();
}
URL url = null;
try {
url = new URL(args[0]);
} catch (MalformedURLException e) {
fatal("Invalid URL: " + args[0]);
}
If args.length < 1, that means no URL was specified on the command line, so a usage message is printed. If the first command-line argument is a good URL, a new URLobject is created to represent it.
Next, JarRunner creates a new instance of JarClassLoader, passing to the constructor the URL that was specified on the command-line:
JarClassLoader cl = new JarClassLoader(url);
As we saw in the previous section, it's through JarClassLoader that JarRunner taps into the JAR-handling APIs.
The URL that's passed to the JarClassLoader constructor is the URL of the JAR-bundled application that you want to run. JarRunner next calls the class loader'sgetMainClassName method to identify the entry-point class for the application:
String name = null;
try {
name = cl.getMainClassName();
} catch (IOException e) {
System.err.println("I/O error while loading JAR file:");
e.printStackTrace();
System.exit(1);
}
if (name == null) {
fatal("Specified jar file does not contain a 'Main-Class'" +
" manifest attribute");
}
The key statement is highlighted in bold. The other statements are for error handling.
Once JarRunner has identified the application's entry-point class, only two steps remain: passing any arguments to the application and actually launching the application.JarRunner performs these steps with this code:
// Get arguments for the application
String[] newArgs = new String[args.length - 1];
System.arraycopy(args, 1, newArgs, 0, newArgs.length);
// Invoke application's main class
try {
cl.invokeClass(name, newArgs);
} catch (ClassNotFoundException e) {
fatal("Class not found: " + name);
} catch (NoSuchMethodException e) {
fatal("Class does not define a 'main' method: " + name);
} catch (InvocationTargetException e) {
e.getTargetException().printStackTrace();
System.exit(1);
}
Recall that the first command-line argument was the URL of the JAR-bundled application. Any arguments to be passed to that application are therefore in element 1 and beyond in the args array. JarRunner takes those elements, and creates a new array called newArgs to pass to the application (bold line above). JarRunner then passes the entry-point's class name and the new argument list to the invokeClass method of JarClassLoader. As we saw in the previous section, invokeClass will load the application's entry-point class, pass it any arguments, and launch the application.

Weblogic WLFULLCLIENT


Prior to the release of weblogic server 10.0, weblogic.jar file could be bundled with the client applications to use some advanced features like:
 - Enhanced JDBC and WLS specific JMX interfaces
 - WLS t3 and iiop client

For information on these featuresOracle Link:

But from WLS 10.0, to use these features, wlfullclient.jar is needed by the client applications. If the applications still use weblogic.jar, it may result in a ClassNotFoundException.

wlfullclient.jar is not available for jdk 1.4, it is only supported and can be made for jdk 1.5 and 1.6.

There are 2 ways of creating wlfullclien.jar using the jarBuilder Tool from the installer. Here is an example of creating the jar file for WLS 10.3, jdk 1.6.

Method 1: - Set the java environment.
 - Run the command C
:\BEA1036\wlserver_10.3\server\lib>java -jar D:/BEA1036/modules/com.bea.core.jarbuilder_1.2.0.0.jar

Method 2: - Set the java environment.
 - Run the command C
:\BEA1036\wlserver_10.3\server\lib>java -jar wljarbuilder.jar -profile wlfullclient

Both the commands create the wlfullclient.jar file in the C:\BEA1036\wlserver_10.3\server\lib directory. This jar file should now be bundled with client applications and should be added to the client application’s classpath for use.

Client
Type
Language
Protocol
Client Class Requirements
Key Features
Java EE Application Client (Thin Client)
(Introduced in WebLogic Server 8.1)
RMI
Java
IIOP
  • wlclient.jar
  • JDK 1.4 and higher
JMS Thin Client
(Introduced in WebLogic Server 8.1)
RMI
Java
IIOP
  • wljmsclient.jar
  • wlclient.jar
  • JDK 1.4 and higher
  • Thin client functionality
  • WebLogic JMS, except for client-side XML selection for multicast sessions and JMSHelper class methods.
  • See WebLogic JMS Thin Client.
JMS SAF Client
RMI
Java
IIOP
  • wlsafclient.jar
  • wljmsclient.jar
  • wlclient.jar
  • JDK 1.4 and higher
T3
RMI
Java
T3
wlfullclient.jar
J2SE
RMI
Java
IIOP
no WebLogic classes
  • Provides connectivity to WLS environment.
  • Does not support WLS-specific features. Does not support many Java EE features.
  • Uses CORBA 2.3 ORB.
  • Requires use of com.sun.jndi.cosnaming.
    CNCtxFactory.
  • See Developing a J2SE Client.
WLS-IIOP
(Introduced in WebLogic Server 7.0)
RMI
Java
IIOP
wlfullclient.jar
JMX
RMI
Java
IIOP
wljmxclient.jar
WebServices
SOAP
Java
HTTP/S
wseeclient.jar
CORBA/IDL
CORBA
Languages that OMG IDL maps to, such as C++, C, Smalltalk, COBOL
IIOP
no WebLogic classes
C++ Client
CORBA
C++
IIOP
Tuxedo libraries
Tuxedo Server and Native CORBA client
CORBA or RMI
C++
Tuxedo-
General-
Inter-Orb-Protocol
(TGIOP)
Tuxedo libraries

Microsoft Windows 7

Normally you can change ownership on a folder through the admin group account...yours. Sometimes, however, Windows will balk. At this point it's usually time to break out the big guns...the hidden administrator account.
You activate this account through the command prompt.
  1. Click the windows orb and type cmd in the search block.
  2. Right click the cmd.exe above the search block and run as administrator.
  3. In the command window type net user administrator /active:yes
  4. Switch users (log onto the administrator account)
  5. Make your ownership changes...if you want to change ownership to this account, complete your deletion here as well.
  6. log off the administrator account and switch back into your normal account.
  7. If you didn't log off, the command window is still active (if you did log off, reopen the command prompt as administrator)
  8. in the command window type net user administrator /active:no*
  9. Exit the command prompt
* If you would like to keep the administrator account active (not recommended, but your choice) you don't need to disabe, but you should include a strong password. This can be done in the command prompt or through the control panel user accounts section. If you forget the password you can always change it with your regular admin account.

Few Shortcut to do the same above Steps:
  1. type cmd in the search block.
  2. CTRL+SHIFT+ENTER.
  3. ALT+Y on pop up to open command prompt in Administrator Mode.