12/05/2013

How to lookup port usage and release the port. (Resolve Issue: Port in-use by unknown process)

When we develop web applications, a very common problem is that sometimes we don't know what is using the current port that we need. And we cann't start our server while getting this kind of exception:


First we could look at the Task Manager to see whether we can get the process which is using this port. But what if we got nothing? Kill every suspects? It's dangerous and sometimes doesn't help at all.
Restart the computer? Ohh that'll work, that's also what I did previously but it's so out!!! It's so painful to restart everything and it's really unneccessary.

Now I get one solution, which is very easy and helpful.

For example, I want to user port "8080" but it's in use by unknown process.

First open the cmd, execute => netstat -aon|findstr "8080"
Then you'll get result like this:
  TCP    0.0.0.0:8080           0.0.0.0:0              LISTENING       87460
  TCP    [::]:8080                 [::]:0                    LISTENING       87460

Now we know who is using the port, the process with PID "87460".

Then in the cmd, we execute => taskkill /pid 87460 -f
Then you'll get result like this:
SUCCESS: The process with PID 87460 has been terminated.

That's it! Then you retart the server, everything will be fine.

12/03/2013

[MongoDB-Escape dots '.' in map key] Resolve org.springframework.data.mapping.model.MappingException: Map key foo.map.key contains dots but no replacement was configured!

Sometimes we need to save map into MongoDB. But the key of the map cannot have dots inside its keys.

If the key has dot(s), by default we'll get this kind of exception:
org.springframework.data.mapping.model.MappingException: Map key foo.bar.key contains dots but no replacement was configured! Make sure map keys don't contain dots in the first place or configure an appropriate replacement!
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.potentiallyEscapeMapKey(MappingMongoConverter.java:622)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeMapInternal(MappingMongoConverter.java:586)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.createMap(MappingMongoConverter.java:517)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writePropertyInternal(MappingMongoConverter.java:424)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter$3.doWithPersistentProperty(MappingMongoConverter.java:386)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter$3.doWithPersistentProperty(MappingMongoConverter.java:373)
    at org.springframework.data.mapping.model.BasicPersistentEntity.doWithProperties(BasicPersistentEntity.java:257)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeInternal(MappingMongoConverter.java:373)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writePropertyInternal(MappingMongoConverter.java:451)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter$3.doWithPersistentProperty(MappingMongoConverter.java:386)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter$3.doWithPersistentProperty(MappingMongoConverter.java:373)
    at org.springframework.data.mapping.model.BasicPersistentEntity.doWithProperties(BasicPersistentEntity.java:257)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeInternal(MappingMongoConverter.java:373)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writePropertyInternal(MappingMongoConverter.java:451)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter$3.doWithPersistentProperty(MappingMongoConverter.java:386)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter$3.doWithPersistentProperty(MappingMongoConverter.java:373)
    at org.springframework.data.mapping.model.BasicPersistentEntity.doWithProperties(BasicPersistentEntity.java:257)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeInternal(MappingMongoConverter.java:373)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeInternal(MappingMongoConverter.java:345)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.write(MappingMongoConverter.java:310)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.write(MappingMongoConverter.java:77)
    at org.springframework.data.mongodb.core.MongoTemplate.doSave(MongoTemplate.java:859)
    at org.springframework.data.mongodb.core.MongoTemplate.save(MongoTemplate.java:806)
    at org.springframework.data.mongodb.core.MongoTemplate.save(MongoTemplate.java:794)


Refer to the source code:

Spring => "MappingMongoConverter.java"
/**
     * Potentially replaces dots in the given map key with the configured map key replacement if configured or aborts
     * conversion if none is configured.
     * 
     * @see #setMapKeyDotReplacement(String)
     * @param source
     * @return
     */
    protected String potentiallyEscapeMapKey(String source) {

        if (!source.contains(".")) {
            return source;
        }

        if (mapKeyDotReplacement == null) {
            throw new MappingException(String.format("Map key %s contains dots but no replacement was configured! Make "
                    + "sure map keys don't contain dots in the first place or configure an appropriate replacement!", source));
        }

        return source.replaceAll("\\.", mapKeyDotReplacement);
    }

So the solution is configure the property mapKeyDotReplacement for bean MappingMongoConverter in the spring config file.

For example:
<bean id="mongoMoxydomainConverter" class="org.springframework.data.mongodb.core.convert.MappingMongoConverter">
        <constructor-arg index="0" ref="mongoDbFactory" />
        <constructor-arg index="1">
            <bean class="org.springframework.data.mongodb.core.mapping.MongoMappingContext" />
        </constructor-arg>
        <property name="mapKeyDotReplacement" value="\\+"/>
</bean>

What needs to be mentioned is that, the value that we set for "mapKeyDotReplacement" must follow the regular pattern's rule. If use reserved character, must use '\\' to translate it.