Monday, December 19, 2011

JAXB Exception: javax.xml.bind.PropertyException: name:


Explanation and Fix:


Sometimes using JAXB, you might need to write following output to the OutputStream object of browser. Intent is to show a minimal UI
on browser by using a XSL file and the XML attributes.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<?xml-stylesheet type='text/xsl' href='../myviewer.xsl'?>
<FileDate>
<DataName>file1.txt</DataName>
</FileData>

To implement this, in your Java code you will write something like this:
        StringWriter sw = new StringWriter();
        JAXBContext context = JAXBContext.newInstance(FileDate.class);
        Marshaller marshaller = context.createMarshaller();
        marshaller.setProperty("com.sun.xml.internal.bind.xmlHeaders", RESOURCE_XSL);
        marshaller.marshal(FileDate, sw);

        Console.WriteLine(sw.getBuffer().toString());
        response.setContentType("application/xml"); //response is object of HttpServletResponse.
        response.getWriter().print(sw.getBuffer().toString());

This works perfectly if you are using JAXB 2.2/ java6 or more. but if your system is confused between old and new java, then it throws this exception:
 Console.WriteLine(sw.getBuffer().toString()); -->will throw exception
javax.xml.bind.PropertyException: name: com.sun.xml.internal.bind.xmlHeaders value: <?xml-stylesheet type='text/xsl' href='../myviewer.xsl'?>

This exception is random and does not appear on all systems. To fix this, use try-catch block and try to use this: com.sun.xml.bind.xmlHeaders

so final code to correct this error will be:
try{
            marshaller.setProperty("com.sun.xml.internal.bind.xmlHeaders", RESOURCE_XSL);
        }
        catch(PropertyException pex)
        {
            marshaller.setProperty("com.sun.xml.bind.xmlHeaders", RESOURCE_XSL);
        }

It should fix the issue.

Sunday, November 13, 2011

Securing or Encrypting Web.config file using command line

We will talk about securing a specific entry in Web.config file using the utilities that ASP.NET provides.
Prerequisites:
(1) Make sure you have information about your current Application's identity. You can know this by writing this code inside your code: "Current Application is running as: " + WindowsIdentity.GetCurrent().Name
(2) By clicking on the IIS management 'sites' tab, you will know the siteID of your application.
Steps:
(1) Modify web.config file to identify the key container (key container is where key will be stored after encryption)
Add This:

type="System.Configuration.RsaProtectedConfigurationProvider,
System.Configuration, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a,processorArchitecture=MSIL"
keyContainerName="MyRSA"
useMachineContainer="true"/>
Here MyRSA is the keycontainername which will be used in future.
(2) You may wish to modify the configuration tag to let it recognize proper XML namespaces:
Otherwise web.config file may not recognize some type above
(3) Create key container on server:
e.g. C:\Windows\Microsoft.NET\Framework\v2.0.50727>aspnet_regiis.exe -pc "MyRSA" -exp
Creating RSA Key container...
Succeeded!
it goes inside
<%ALLUSERSPROFILE%\Application Data\Microsoft\Crypto\RSA\MachineKeys> You can check the modified date
(4) Grant access to the key container. Access should be given to the application's identity. Application's identity is the one from prerequisite step 1 above. For me it was "IIS APPPOOL\DefaultAppPool"
e.g. C:\Windows\Microsoft.NET\Framework\v2.0.50727>aspnet_regiis -pa "MyRSA" "IIS APPPOOL\DefaultAppPool"
Adding ACL for access to the RSA Key container...
Succeeded!
(5) Same as 4 above:
e.g. C:\Windows\Microsoft.NET\Framework\v2.0.50727>aspnet_regiis -pa "NetFrameworkConfigurationKey" "IIS APPPOOL\DefaultAppPool"
Adding ACL for access to the RSA Key container...
Succeeded!
(6) Encrypt the entry inside Web.config file. I wanted to encrypt the connectionStrings section of my Web.config file.
e.g. C:\Windows\Microsoft.NET\Framework\v2.0.50727>aspnet_regiis -pe "connectionStrings" -app "/ui1" -site "1"
Encrypting configuration section...
Succeeded!
For me, siteid was 1 shown in IIS console. and 'ui1' was the alias name for my application1.
(7) If you want to encypt another UI app with same key, you can run again.
e.g. C:\Windows\Microsoft.NET\Framework\v2.0.50727>aspnet_regiis -pe "connectionStrings" -app "/ui2" -site "1"
Encrypting configuration section...
Succeeded!
You can see that siteID is same for both of the apps.

NOTE: 1. If you want to modify the username/passwords or other sensitive information inside Web.config file, decrypt the config file, edit/save and encrypt again.
Command to decrypt the connectionStrings:
run: aspnet_regiis.exe -pd "connectionStrings" -app "/ui1" -site "1"

for app2: aspnet_regiis.exe -pd "connectionStrings" -app "/ui2" -site "1"

After changing passwords, run step 6 and 7 again.

2. C# code automatically decrypts the Web.config file entries when application runs so no need to write extra code.

Hope this helps....

Friday, March 4, 2011

Android Error: alert dialog crashes during create() or return call

Suppose you launch your main activity named 'myMainActivity' which was mentioned as main activity in your manifest file. Then you navigate to a new page named 'myFiles' page using a new Intent(). Both of these classes extend Activity(). suppose there is a menu option on your 'myFiles' page which allows users to do some operation and based on user's response you have to show some alert dialog. First you will create menu items either using java code or XML file and load them inside. We are not going into that detail. We are going to discuss how to show alert dialog in this case. If you know the place where you need to show the dialog, then write this code there:
showDialog(int_value); //int_value is just a value which is user defined and we will use this to identify our dialog and also android will use this value while calling our dialog handlers.

override onCreateDialog(..) method :
*** If you use the help guides or documents to write this, you will write it as mentioned below and your program will crash while showing the dialog. ****

@Override
protected Dialog onCreateDialog(int id) {
AlertDialog alert = null;
switch( id ) {
case int_value:
AlertDialog.Builder builder = new AlertDialog.Builder(this); //remember it
builder.setMessage("Are you sure you want to exit?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
}})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}});
alert = builder.create();
}
return alert; //THIS WILL CRASH

}

Reason: Reason is simple. AlertDialog.Builder() constructor expects the current activity's context where this dialog is running. If you give 'this', then it points to context which is for current intent and during show() method, when it tries to associate itself with 'this' pointer's activity, it fails to do so because that is not the main activity.

Solution: Go to your main activity java code. Put a static Context variable say 'myMainContext' and initialize it inside onCreate() method of main activity page. Use that static context variable while constructing your builder class.

So after modification the constructor will be like this: AlertDialog.Builder builder = new AlertDialog.Builder(myMainPage.myMainContext);

This should solve the problem.