Monday, November 28, 2016

Maven Proxy Setting in NetBeans IDE

NetBeans IDE proxy setting is under Tools -> Options -> General.

But, in order for the Maven to use the proxy, you need to set the proxy for Maven separately at the following file.

<Netbeans Install Dir>/java/maven/conf/settings.xml 

Look for <proxies> tag and add or edit proxy information accordingly as the following.

<proxies>
      <proxy>
          <id>optional</id>
  <active>true</active>
  <protocol>http</protocol>
  <username></username>
  <password></password>
  <host>proxy.myhost.com</host>
  <port>8080</port>
          <nonProxyHosts>localhost</nonProxyHosts>
      </proxy>
      <proxy>
          <id>optional</id>
  <active>true</active>
          <protocol>https</protocol>
          <username></username>
  <password></password>
  <host>proxy.myhost.com</host>
          <port>8080</port>
  <nonProxyHosts>localhost</nonProxyHosts>
     </proxy>
<proxies>

Wednesday, June 29, 2016

Some projects cannot be imported because they already exist in the workspace in Eclipse

When you try to import an existing project into workspace in Eclipse or Spring Tool Suite, and cannot import because of this error,

Some projects cannot be imported because they already exist in the workspace

then you can try the following.

Open the ".project" file from the project directory and change the project name in the <name> tag. That's it. And try to import again.

Friday, June 17, 2016

Turning on Oracle Compatibility Mode in DB2

Both full DB2 and DB2 Express C shipped with the Oracle Compatibility Mode, which can be turned on.

Launch the DB2 Administrator command window and issue the following commands. 

     db2set DB2_COMPATIBILITY_VECTOR=ORA

     db2set DB2_DEFERRED_PREPARE_SEMANTICS=YES

Then, restart the database. 

     db2stop

     db2start

Then create a new database and that database is already compatible with Oracle. 

     db2 CREATE DATABASE DB_Name

Thursday, June 9, 2016

Oracle to DB2 Migration - NULL Unique Constraint

Oracle allows columns of the unique constraint to be NULL.

CREATE  TABLE MYTABLE
  (
         ID      VARCHAR2(9),
         CD     VARCHAR2(6),
         UNIQUE (ID, CD)
  );

This is OK in Oracle. But if you run the same script in DB2, you will have an error with the error code, SQLCODE=-542. The reason is you must explicitly declare all the columns of the unique constraint as NOT NULL in DB2. So only the following script will work. 

CREATE  TABLE MYTABLE
  (
         ID      VARCHAR2(9)   Not NULL,
         CD     VARCHAR2(6)   Not NULL,
         UNIQUE (ID, CD)
  );

But with the above script, if you are migrating the existing data from Oracle to DB2, the migration will fail with the error code SQLCODE=-407 if the existing data includes NULL in one of those columns because both columns of the above script do not allow NULL values. 

The good news is that starting with the DB2 10.5, EXCLUDE NULL KEYS on unique index is introduced. So the problem can be solved by creating a UNIQUE INDEX separately as the following. 

CREATE  TABLE MYTABLE
  (
         ID      VARCHAR2(9),
         CD     VARCHAR2(6)
  );

CREATE   UNIQUE  INDEX   MYTABLE_U01  ON   MYTABLE (ID, CD)   EXCLUDE NULL KEYS;


Sunday, May 22, 2016

Uninstall applications manually from Websphere

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 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.