Sometimes, when you try to uninstall an application from the Websphere admin console, for whatever reason, it would fail with the following message displayed at the top of the admin console,
An error occurred while uninstalling <<your_app>>. Check the logs for more details.
with the following error message in SystemOut.log.
UninstallSche I ADMA5107E: The application <<your_app>> cannot be uninstalled.
When that happens, you will need to uninstall the application manually, and to do that, first, delete your_app.ear folders from the following two locations.
<Websphere-install-dir>/AppServer/profiles/<<your_profile>>/installedApps/<<your_cell>>
And
<Websphere-install-dir>/AppServer/profiles/<<your_profile>>/config/cells/<<your_cell>>/applications.
Then empty all the contents from the following two folders.
<Websphere-install-dir>/AppServer/profiles/<<your_profile>>/temp
<Websphere-install-dir>/AppServer/profiles/<<your_profile>>/wstemp
Next, go to the following folder and edit serverindex.xml.
<Websphere-install-dir>/AppServer/profiles/<AppSrvxx>/config/cells/<<your_cell>>/nodes/<<your_node>>/serverindex.xml
And delete the lines that has <<your_app.ear>> such as
<deployedApplications><<your_app.ear>>/deployments/<<your_app_war>></deployedApplications>
and/or
<extendedApplicationDataElements xmi:id="ExtendedApplicationData_xxxxxxx" applicationName="<<your_app_war>>" standaloneModuleName="<<your_app.war>>"/>
That's it. Restart the server your will no longer see the application in the server.
Sunday, May 22, 2016
Sunday, May 15, 2016
Static Code Analysis Tool, Cross Site Scripting (XSS), a Fix and a Good Practice
You can always print out an attribute simply like this in JSP pages, assuming myAttr is the attribute name.
${myAttr}
But if the origin of that attribute is actually a request parameter that is coming straight from the user input, then by printing in JPS page that way, you make yourself vulnerable to the Cross Site Scripting. The fix to this Cross Site Scripting vulnerability is to escape HTML. By default, <c:out> prints its value by escaping HTML. Therefore, using <c:out> to print the attribute the following way
<c:out value="${myAttr}"/>
will automatically fix the vulnerability.
If myAttr attribute is not directly coming from the user input, then it's safe to print without <c:out>. But if your company or your client uses Static Code Analysis tool to scan your code as standard practice, those tools will normally flag as Cross Site Scripting vulnerability once they detect printing this way, ${myAttr}, in JSP pages whether or not that attribute is coming from the user input.
If you are sure that myAttr is actually not coming from the user input, then you can define the flag as "false positive". But it's gonna be very annoying to keep coming back every time your code is scanned by those tools. And what's more, it's usually company policy to fix as many flags as possible whether they are real vulnerabilities or false positives.
So it's a good practice or become an industry best practice to always print out an attribute using <c:out> the following way
<c:out value="${myAttr}"/>
whether the attribute is really vulnerable or not.
Saturday, May 14, 2016
Getting Column Names Or Table Dynamically in MyBatis
Most of the time, you know exactly the column names of a database table you are retrieving the data from. But there might be times when you just want to display the table dynamically without knowing the column names beforehand, for instance when you need to write an admin module.
If you use normal JDBC, you normally use the ResultSetMetaData object to achieve that and you can get all the column names from there. But how are you gonna do it in MyBatis? There are some other more complicated ways to do it but this is the simplest and the most straight forward.
The solution is to use resultType instead of resultMap in MyBatis mapping config as the following.
<select resultType="java.util.LinkedHashMap" id="getTableData " parameterType="String">
${queryString}
</select>
We use java.util.LinkedHashMap for resultType. You can also use normal HashMap but you might not wanna use that because HashMap doesn't maintain the insertion order. That's about it for the configuration. You do not need to configure the mapper for the resultType like resultMap because MyBatis automatically populates the results in LinkedHashMap for you.
So let's suppose, this is the MyBatis DAO interface.
public interface Xyz {
public List<Map> getTableData(Query query);
}
Note the return type. It must be a List. MyBatis returns a list of Map objects. One Map object represents one row of data.
In a Map object, the "key" is column name and the value is the value of that column in the respective row.
This is it. Call the method and now you've got all the column names and values.
If you need column names, you can just call keySet() from the Map object and you will get all the column names in a Set.
Just iterate through the List, iterate through each Map object inside, print it out and experiment with it. You will know what you have to do next.
If you use normal JDBC, you normally use the ResultSetMetaData object to achieve that and you can get all the column names from there. But how are you gonna do it in MyBatis? There are some other more complicated ways to do it but this is the simplest and the most straight forward.
The solution is to use resultType instead of resultMap in MyBatis mapping config as the following.
<select resultType="java.util.LinkedHashMap" id="getTableData " parameterType="String">
${queryString}
</select>
We use java.util.LinkedHashMap for resultType. You can also use normal HashMap but you might not wanna use that because HashMap doesn't maintain the insertion order. That's about it for the configuration. You do not need to configure the mapper for the resultType like resultMap because MyBatis automatically populates the results in LinkedHashMap for you.
So let's suppose, this is the MyBatis DAO interface.
public interface Xyz {
public List<Map> getTableData(Query query);
}
Note the return type. It must be a List. MyBatis returns a list of Map objects. One Map object represents one row of data.
In a Map object, the "key" is column name and the value is the value of that column in the respective row.
This is it. Call the method and now you've got all the column names and values.
If you need column names, you can just call keySet() from the Map object and you will get all the column names in a Set.
Just iterate through the List, iterate through each Map object inside, print it out and experiment with it. You will know what you have to do next.
Subscribe to:
Posts (Atom)