Warning: "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? in /homepages/17/d489878761/htdocs/blog/wp-content/plugins/wp-markdown/markdownify/markdownify.php on line 299

Warning: Creating default object from empty value in /homepages/17/d489878761/htdocs/blog/wp-content/plugins/wptouch/core/admin-load.php on line 106

Warning: Cannot modify header information - headers already sent by (output started at /homepages/17/d489878761/htdocs/blog/wp-content/plugins/wp-markdown/markdownify/markdownify.php:299) in /homepages/17/d489878761/htdocs/blog/wp-includes/feed-rss2.php on line 8
Guru https://blog.pengyifan.com Insights from Yifan into technology, algorithms, products, and tricks Sun, 16 Apr 2017 19:13:19 +0000 en-US hourly 1 https://wordpress.org/?v=5.3.7 https://blog.pengyifan.com/wp-content/uploads/2013/12/cropped-blog-32x32.png Guru https://blog.pengyifan.com 32 32 《Deep Learning》(深度学习)中文版开放下载 https://blog.pengyifan.com/%e3%80%8adeep-learning%e3%80%8b%ef%bc%88%e6%b7%b1%e5%ba%a6%e5%ad%a6%e4%b9%a0%ef%bc%89%e4%b8%ad%e6%96%87%e7%89%88%e5%bc%80%e6%94%be%e4%b8%8b%e8%bd%bd/ https://blog.pengyifan.com/%e3%80%8adeep-learning%e3%80%8b%ef%bc%88%e6%b7%b1%e5%ba%a6%e5%ad%a6%e4%b9%a0%ef%bc%89%e4%b8%ad%e6%96%87%e7%89%88%e5%bc%80%e6%94%be%e4%b8%8b%e8%bd%bd/#comments Sun, 16 Apr 2017 19:13:19 +0000 http://blog.pengyifan.com/?p=837 Deep Learning》(深度学习)是一本皆在帮助学生和从业人员进入机器学习领域的教科书,以开源的形式免费在网络上提供,这本书是由 Ian Goodfellow、Yoshua Bengio 和 Aaron Courville 合力打造。

这本书的主题具体来说,是机器学习的一种,一种能够使计算机系统从经验和数据中得到提高的技术。深度学习是一种特定类型的机器学习,具有强大的能力和灵活性,它将大千世界表示为嵌套的层次概念体系(由较简单概念间的联系定义复杂概念、从一般抽象概括到高级抽象表示)。对于本书的结构,第一部分介绍基本的数学工具和机器学习的概念,第二部分介绍最成熟的深度学习算法,而第三部分讨论某些具有展望性的想法,它们被广泛地认为是深度学习未来的研究重点。

因此,本书从基础数学知识到各类深度方法全面而又深入地描述了深度学习的各个主题。译者们也相信开源此书 PDF 版的中文译文可以促进大家对深度学习的基础和前沿知识有进一步的理解,也相信通过开放高质量的专业书籍能做到先阅读后付费。

But, “开源也涉及版权问题,出于版权原因,我们不再更新此初版PDF文件,请大家以最终的纸质版为准。”

]]>
https://blog.pengyifan.com/%e3%80%8adeep-learning%e3%80%8b%ef%bc%88%e6%b7%b1%e5%ba%a6%e5%ad%a6%e4%b9%a0%ef%bc%89%e4%b8%ad%e6%96%87%e7%89%88%e5%bc%80%e6%94%be%e4%b8%8b%e8%bd%bd/feed/ 1
Where to place you own .sty or .cls files, to make them available to all my .tex files? https://blog.pengyifan.com/where-to-place-you-own-sty-or-cls-files-to-make-them-available-to-all-my-tex-files/ https://blog.pengyifan.com/where-to-place-you-own-sty-or-cls-files-to-make-them-available-to-all-my-tex-files/#respond Tue, 24 May 2016 21:25:47 +0000 http://blog.pengyifan.com/?p=789 Read More »]]> Suppose you have defined a package or a class, but how do you make it available at all times? One way is to just place it in the same folder as the .tex file, but that’s not what I’m after here. This post will tell you a way to “install” the package centrally on your computer.

1. Find out the directory. First, use this command at the command prompt to find out where your TeX home directory is.

kpsewhich -var-value=TEXMFHOME
OS Location
Windows C:/Users/stefan/texmf
Unix-type ~/texmf/
Mac ~/Library/texmf

2. Place files in the “right place”. Following the TeX directory structure, you should place your file in the “right place” like ~/texmf/tex/latex/packagename/packagename.sty. For a TDS-conformant system (TeX Directory Structure), the “right place” for a LaTeX .sty file is a suitably-named subdirectory of texmf/tex/latex/. For a full list of “right place”s, please see LaTeX/Installing Extra Packages. Moreover, for the beamer style, put the theme under beamer/themes/ with “color”, “font”, “inner”, “outer”, and “theme” in seperated subdirectories.

3. Update your index. Finally, run your TeX indexer program to update the package database.

Version of TeX Program
teTeX, TeX Live, fpTeX texhash
web2c mktexlsr
MacTeX
MikTeX initexmf

I am using texlive, so I run

texhash ~/texmf 

This will generate a ls-R file in the directory.

]]>
https://blog.pengyifan.com/where-to-place-you-own-sty-or-cls-files-to-make-them-available-to-all-my-tex-files/feed/ 0
Dropbox icon is not working Xubuntu 16.04 LTS https://blog.pengyifan.com/dropbox-icon-is-not-working-xubuntu-16-04-lts/ https://blog.pengyifan.com/dropbox-icon-is-not-working-xubuntu-16-04-lts/#comments Fri, 22 Apr 2016 03:46:56 +0000 http://blog.pengyifan.com/?p=784 After upgrading to Xubuntu 16.04, I found that the dropbox icon stopped working. The icon is black with a red slashed zero. I cannot click on it to bring up the dropbox menu.

The reason is that Dropbox starts to use “indicator area” for their tray icon instead of “notification area”. The problem can be fixed by running

$ dropbox stop && DBUS_SESSION_BUS_ADDRESS="" dropbox start

or

$ dropbox stop && dbus-launch dropbox start
]]>
https://blog.pengyifan.com/dropbox-icon-is-not-working-xubuntu-16-04-lts/feed/ 6
How to ignore namespace when selcting XML nodes with XPath https://blog.pengyifan.com/how-to-ignore-namespace-when-selcting-xml-nodes-with-xpath/ https://blog.pengyifan.com/how-to-ignore-namespace-when-selcting-xml-nodes-with-xpath/#respond Sun, 10 Apr 2016 01:43:49 +0000 http://blog.pengyifan.com/?p=775 <OAI-PMH xmlns="http://www.openarchives.org/OAI/2.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd"> <responseDate>2016-04-08T01:08:52Z</responseDate> <request verb="GetRecord" identifier="oai:pubmedcentral.nih.gov:2702331" metadataPrefix="pmc">http://www.ncbi.nlm.nih.gov/oai/oai.cgi</request> <GetRecord> <record> <header> <identifier>oai:pubmedcentral.nih.gov:2702331</identifier> <datestamp>2009-06-27</datestamp> <setSpec>retrovir</setSpec> <setSpec>pmc-open</setSpec> </header> <metadata> <article xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://dtd.nlm.nih.gov/ns/archiving/2.3/" xsi:schemaLocation="http://dtd.nlm.nih.gov/ns/archiving/2.3/ http://dtd.nlm.nih.gov/archiving/2.3/xsd/archivearticle.xsd" article-type="research-article"> <front> <article-meta> <article-id pub-id-type="accession">PMC2702331</article-id> <article-id pub-id-type="pmcid">PMC2702331</article-id> <article-id pub-id-type="pmc-uid">2702331</article-id> <article-id pub-id-type="publisher-id">1742-4690-6-47</article-id> <article-id pub-id-type="pmid">19454010</article-id> ... How to ignore namespace when selecting XML nodes with XPath? One way is to use local-name()… Read More »]]> I have several full article in PMC XML format to parse. I plan to use XPath. However, the namespace always breaks my path. For example, in the following XML I cannot use *//article-id to retrieve all article-id tags. Instead, I have to use *//{http://dtd.nlm.nih.gov/ns/archiving/2.3/}article-id. As you can see, it is really painful.

<?xml version="1.0" encoding="UTF-8"?><OAI-PMH
    xmlns="http://www.openarchives.org/OAI/2.0/" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
    <responseDate>2016-04-08T01:08:52Z</responseDate>
    <request verb="GetRecord" identifier="oai:pubmedcentral.nih.gov:2702331" metadataPrefix="pmc">http://www.ncbi.nlm.nih.gov/oai/oai.cgi</request>
    <GetRecord>
        <record>
            <header>
                <identifier>oai:pubmedcentral.nih.gov:2702331</identifier>
                <datestamp>2009-06-27</datestamp>
                <setSpec>retrovir</setSpec>
                <setSpec>pmc-open</setSpec>
            </header>
            <metadata>
                <article xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://dtd.nlm.nih.gov/ns/archiving/2.3/" xsi:schemaLocation="http://dtd.nlm.nih.gov/ns/archiving/2.3/ http://dtd.nlm.nih.gov/archiving/2.3/xsd/archivearticle.xsd" article-type="research-article">
                      <front>
                        <article-meta>
                          <article-id pub-id-type="accession">PMC2702331</article-id>
                          <article-id pub-id-type="pmcid">PMC2702331</article-id>
                          <article-id pub-id-type="pmc-uid">2702331</article-id>
                          <article-id pub-id-type="publisher-id">1742-4690-6-47</article-id>
                          <article-id pub-id-type="pmid">19454010</article-id>
...

How to ignore namespace when selecting XML nodes with XPath? One way is to use local-name() function in XPath, such as */[local-name()='article-id']. But it is still inconvenient.

In Python, I use lxml with the following code.

parser = etree.XMLParser(remove_blank_text=True)
tree = etree.parse(metadata, parser)
root = tree.getroot()

####    
for elem in root.getiterator():
    if not hasattr(elem.tag, 'find'): continue
    i = elem.tag.find('}')
    if i >= 0:
        elem.tag = elem.tag[i+1:]
objectify.deannotate(root, cleanup_namespaces=True)
####

The above code does three things:

  1. remove {namespace} if it appears in the tag
  2. some tags like Comment return a function when accessing tag attribute. Skip that
  3. use lxml.objectify.deannotate to recursively de-annotate the elements of an XML tree by removing py:pytype and/or xsi:type attributes and/or xsi:nil attributes.

As a result, XPath .//article-id will do the job.

]]>
https://blog.pengyifan.com/how-to-ignore-namespace-when-selcting-xml-nodes-with-xpath/feed/ 0
Three steps to test PHP locally without installing a server https://blog.pengyifan.com/three-steps-to-test-php-locally-without-installing-a-server/ https://blog.pengyifan.com/three-steps-to-test-php-locally-without-installing-a-server/#respond Tue, 15 Mar 2016 17:14:07 +0000 http://blog.pengyifan.com/?p=771 1. Install PHP 5.5+ which has a built-in server
sudo apt-get install php5

2. Create a directory for php files. For example public_html/index.php

3. Run

php -S localhost:8000

4. Check http://localhost:8000/index.php

]]>
https://blog.pengyifan.com/three-steps-to-test-php-locally-without-installing-a-server/feed/ 0
How to return an subclass with generics https://blog.pengyifan.com/how-to-return-an-subclass-with-generics/ https://blog.pengyifan.com/how-to-return-an-subclass-with-generics/#respond Sat, 05 Mar 2016 22:25:11 +0000 http://blog.pengyifan.com/?p=765 { private E obj; ... public Tree getChild(int index) {...} } One way is to return Tree, but it makes difficult if we need to subclass of Tree. For example, in StringTree that extends Tree, the return type is still Tree. Ideally, we need StringTree. Of course, we can use… Read More »]]> In 2013, I created a project to provide a general-purpose tree structure in Java.

One challenge at that time (mostly because I was not an expertise at that time, neither am I now) is the return type of Tree methods. For example, the return type of getChild(int index) that should return the child at the specified index.

public class Tree<E>  {
  private E obj;
  ...
  public Tree getChild(int index) {...}
}

One way is to return Tree, but it makes difficult if we need to subclass of Tree. For example, in StringTree that extends Tree, the return type is still Tree. Ideally, we need StringTree. Of course, we can use cast Tree to StringTree every time we call the method

public class StringTree extends Tree<String>  {
}

StringTree firstChild = (StringTree)t.getChild(0);

But we can do it better.

public class Tree<E, T extends Tree<E, T>> {
  private E obj;
  ...
  public T getChild(int index) {...}
}

By this way, StringTree#getChild(int index) will return StringTree.

]]>
https://blog.pengyifan.com/how-to-return-an-subclass-with-generics/feed/ 0
How to use Whatizit Web Services in Java https://blog.pengyifan.com/how-to-use-whatizit-web-services-in-java/ https://blog.pengyifan.com/how-to-use-whatizit-web-services-in-java/#comments Fri, 13 Nov 2015 21:49:23 +0000 http://blog.pengyifan.com/?p=755 Read More »]]> Whatizit is a text processing system that allows you to do textmining tasks on text. It is also available as a Web Service whose underlying idea is to ensure that software from various sources work well together. Whatizit is built on open standards of Simple Object Access Protocol (SOAP) and Web Services Description Language (WSDL). For the transport layer itself, Web Services uses most of the commonly available network protocols, especially Hypertext Transfer Protocol (HTTP). For more information on WSDL please refer to the W3C WSDL v1.1 Document.

To use Whatizit web service, you need a directory structure like the following:

  • whatizitws/core/SoapClient.java. Download from Whatizit example Web Services client)
  • jaxws-ri. Download from JAX-WS. You need to download the zip file and extract it in the directory. You will have a new directory jaxws-ri with all the necessary jars in jaxws-ri/lib and scripts in jaxws-ri/bin.
  • generated (An empty folder)
  • src (An empty folder)
  • whatizit.wsdl. Download from Whatizit’s WSDL. You need to rename it
  • server-binding.xml. Download from server-binding.xml.

set PATH shell environment variable pointing to jaxws-ri/bin, you will be able to execute:

wsimport.sh -p whatizitws.client -s src -b server-binding.xml \
  -d generated whatizit.wsdl

which will generate the Stubs. The actual source code for the Stubs can be found in the src folder. The actual class files for the Stubs can be found in the generated folder.

To use the webservice, we firstly need to check out the available pipelines. The description of each individual task/pipeline can be found at http://www.ebi.ac.uk/webservices/whatizit/info.jsf.

To list available pipelines, uncomment line 49-57, then compile and run the client

javac -extdirs jaxws-ri/lib -cp generated whatizitws/core/SoapClient.java
java -Djava.ext.dirs=jaxws-ri/lib -cp generated:. \
  whatizitws.core.SoapClient 

You will get a list of available pipelines, such as

PipelineName: whatizitUkPmcDisease
Description: 
Available: true

PipelineName: whatizitMeshUp
Description: MeshUp annotation
Available: true

PipelineName: whatizitUkPmcGenesProteins
Description: 
Available: true
...

Then pick the pipeline name and try contact, queryPmid, and search in SoapClient.java by replacing the pipelineName at Line 60.

]]>
https://blog.pengyifan.com/how-to-use-whatizit-web-services-in-java/feed/ 2
How to submit a package to PyPI https://blog.pengyifan.com/how-to-submit-a-package-to-pypi/ https://blog.pengyifan.com/how-to-submit-a-package-to-pypi/#respond Fri, 30 Oct 2015 00:35:03 +0000 http://blog.pengyifan.com/?p=750 Read More »]]> How to submit a package to PyPI

PyPI (Python Package Index) is a repository of software for the Python programming language. This article will tell you how to submit your package to PyPI, so others are able to install it with easy_install or pip. The offical document is at http://wiki.python.org/moin/CheeseShopTutorial#Submitting_Packages_to_the_Package_Index

Create your accounts

You must create accounts on PyPI Live and PyPI Test before upload your code.

After registration, create a pypirc configuration file at ~/. This file holds your information for authenticating with PyPI, both the live and the test versions.

[distutils]
index-servers =
  pypi
  pypitest

[pypi]
repository: https://pypi.python.org/pypi
username: {{your_username}}
password: {{your_password}}

[pypitest]
repository: https://testpypi.python.org/pypi
username: {{your_username}}
password: {{your_password}}

Prepare your package

Every package on PyPI needs to have a file called setup.py at the root of the directory. If you are using a markdown-formatted README file you’ll also need a setup.cfg file. Also, you’ll want a LICENSE.txt file describing what can be done with your code. So the directory structure would look like this:

root-dir/
  setup.py
  setup.cfg
  LICENSE.txt
  README.md
  mypackage/
    __init__.py
    file1.py
    file2.py
    file3.py

setup.py

This is metadata about your library.

from distutils.core import setup
setup(
  name = 'mypackage',
  packages = ['mypackage'],
  version = '0.1',
  description = 'A random test lib',
  author = 'Peter Downs',
  author_email = 'your email address',
  url = 'https://github.com/yfpeng/mypackage',
  keywords = ['testing', 'logging', 'example'],
  classifiers = [],
)

setup.cfg

This tells PyPI where your README file is.

[metadata]
description-file = README.md

Upload your package to PyPI

Run the following code to
1. Register your package against PyPI (and test) server, to make sure you’ve set up everything correctly.
2. Upload the package to PyPI (and test) server

python setup.py register -r pypitest
python setup.py sdist upload -r pypitest
python setup.py register -r pypi
python setup.py sdist upload -r pypi
]]>
https://blog.pengyifan.com/how-to-submit-a-package-to-pypi/feed/ 0
How to create a Web Application Project with Java/Maven/Jetty https://blog.pengyifan.com/how-to-create-a-web-application-project-with-javamavenjetty/ https://blog.pengyifan.com/how-to-create-a-web-application-project-with-javamavenjetty/#comments Wed, 12 Aug 2015 15:07:35 +0000 http://blog.pengyifan.com/?p=734 Read More »]]> How to create a Web Application Project with Java/Maven/Jetty or Tomcat

In this article, we create a simple web application with the Maven Archetype plugin. We’ll run this web application in a Servlet container named Jetty, add some dependencies, write simple Servlets, and generate a WAR file. At the end of this article, you will also be able to deploy the service in Tomcat.

System requirements

Creating the Web Service Step by Step

This section explains how to create this simple web project from an EMPTY folder.

Creating the Simple Web Project

To create your web application

$ mvn archetype:generate -DgroupId=com.pengyifan.simpleweb \
      -DartifactId=simple-webapp \
      -Dpackage=com.pengyifan.simpleweb \
      -DarchetypeArtifactId=maven-archetype-webapp \
      -Dversion=1.0-SNAPSHOT \
      -DinteractiveMode=false

...
[INFO] BUILD SUCCESS

Once the Maven Archetype plugin creates the project, change the directory into the simple-webapp directory and take a look at the pom.xml. You should see the

<project xmlns="http://maven.apache.org/POM/4.0.0" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
  http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.pengyifan.simpleweb</groupId>
  <artifactId>simple-webapp</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>simple-webapp Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <build>
    <finalName>simple-webapp</finalName>
  </build>
</project>

Notice the packaging element contains the value war. This packaging type is what configures Maven to produce a web application archive in a WAR file. A project with war packaging is going to create a WAR file in the target directory. Thus, the default name of this file is ${artifactId}-${version}.war. In this Maven project, the default WAR would be generated in target/simple-webapp-1.0-SNAPSHOT.war. Furthermore, we’ve customized the name of the generated WAR file by adding a finalName element inside of this project’s build configuration. With a finalName of simple-webapp, the package phase produces a WAR file in target/simple-webapp.war.

Next, you will need to configure

  1. Maven Compiler plugin to target Java version (JDK 8 in this article)
  2. Java Servlet dependency.
  3. Maven Jetty Plugin.

The pom.xml should look like this. You can also overwrite pom.xml using the one in the downloaded package.

<project xmlns="http://maven.apache.org/POM/4.0.0" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
  http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.pengyifan.simpleweb</groupId>
  <artifactId>simple-webapp</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>simple-webapp Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>2.4</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>
  <build>
    <finalName>simple-webapp</finalName>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.mortbay.jetty</groupId>
        <artifactId>maven-jetty-plugin</artifactId>
        <version>6.1.26</version>
        <configuration>
          <connectors>
            <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
              <port>80</port>
            </connector>
          </connectors>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

Now, you can invoke the Run goal of the Jetty plugin to start your web application in the Jetty Servlet container. Run:

$ mvn jetty:run

Note that mvn jetty:run will continue to run the Jetty servlet container until you stop the process with CTRL-C.

After Maven starts the Jetty Servlet container, load the URL http://localhost/simple-webapp/index.jsp in a web browser. The simple index.jsp generated by the Archetype is trivial; it contains a second-level heading with the text “Hello World!”. Maven expects the document root of the web application to be stored in src/main/webapp. It is in this directory where you will find the index.jsp file.


Hello World!

In src/main/webapp/WEB-INF, we will find the smallest possible web application web.xml, shown in this next example:


<web-app>
  <display-name>Archetype Created Web Application</display-name>
</web-app>

Adding a Simple Servlet

A web application with a single page and no configured servlets is next to useless. Let’s add a simple servlet to this application and make some changes to the pom.xml and web.xml to support this change. First, we’ll need to create a new package under src/main/java named com.pengyifan.web:

$ mkdir -p src/main/java/com/pengyifan/web
$ cd src/main/java/com/pengyifan/web

Once you’ve created this package, change to the src/main/java/com/pengyifan/web directory and create a class named SimpleServlet:

package com.pengyifan.web;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class SimpleServlet extends HttpServlet {
  @Override
  public void doGet(HttpServletRequest request, 
      HttpServletResponse response)
      throws ServletException, IOException {
    doPost(request, response);
  }

  @Override
  public void doPost(HttpServletRequest request, 
      HttpServletResponse response)
      throws ServletException, IOException {
    PrintWriter out = response.getWriter();
    out.println("SimpleServlet Executed");
    out.flush();
    out.close();
  }
}

Our SimpleServlet class is just that: a servlet that prints a simple message to the response’s Writer. Now we need to add this servlet to your web application and map it to a request path. You can change web.xml in src/main/webapp/WEB-INF.

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <servlet>
    <servlet-name>simple</servlet-name>
    <servlet-class>
      com.pengyifan.web.SimpleServlet
    </servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>simple</servlet-name>
    <url-pattern>/simple</url-pattern>
  </servlet-mapping>
</web-app>

Everything is in place to test this servlet. Run:

$ mvn clean install
...
$ mvn jetty:run
[INFO] [jetty:run]
...
[INFO] Started Jetty Server

At this point, you should be able to retrieve the output of the SimpleServlet. From the web browser, you can load http://localhost:8080/simple-webapp/simple, and get SimpleServlet Executed.

Changing the port

In the source package, we use the port 80. In this task, we recommend you to listen on port 80 for the RESTful API. But we could still listen to other ports. To do so, find the following lines in the pom.xml file, and change the number in <port>.

[...]
<plugin>
  <groupId>org.mortbay.jetty</groupId>
  <artifactId>maven-jetty-plugin</artifactId>
  <version>6.1.26</version>
  <configuration>
    <connectors>
      <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
        <port>80</port>
      </connector>
    </connectors>
  </configuration>
</plugin>
[...]

Enabling SSL

For security reason, we might needto enable SSL communication between the server and client. So when we run mvn jetty:run we must be able to use the https protocol. For development we can create our own security certificate and configure the plugin to use it.

To create the development certificate we run the following command:

keytool -genkey -alias jetty6 -keyalg RSA \
  -keystore target/jetty-ssl.keystore \
  -storepass jetty6 -keypass jetty6 \
  -dname "CN=your name or domain"

Fill in your name or domain for the -dname "CN=" option. We need the keystore and key password again when we configure the plugin in the Maven pom.xml. The following code fragment shows how the Jetty plugin supports SSL:

<plugin>
  <groupId>org.mortbay.jetty</groupId>
  <artifactId>maven-jetty-plugin</artifactId>
  <configuration>
    <connectors>
      <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
        <port>8080</port>
      </connector>
      <connector implementation="org.mortbay.jetty.security.SslSocketConnector">
        <port>8081</port>
        <maxIdleTime>60000</maxIdleTime>
        <keystore>${project.build.directory}/jetty-ssl.keystore</keystore>
        <password>jetty6</password>
        <keyPassword>jetty6</keyPassword>
      </connector>
    </connectors>
  </configuration>
</plugin>

In the connectors element we have defined connectors for http listening on port 8080, and for https listening on port 8081. Under <keystore>, we reference the keystore file we have created with keytool. <password> and <keyPassword> define the password value.

To test this configuration we can invoke mvn jetty:run and open a web browser with address https://localhost:8081/simple-webapp/. We must not forget to use https for the protocol.

We generated the keystore by using the keytool command from the Java Development Kit. But there is a Maven plugin that does the same thing, but we can define all arguments for keytool in our POM. When we run mvn keytool:generateKeyPair, the keystore is generated and with mvn keytool:clean we can remove the keystore again. If we want to attach the creation of the keystore to the Maven generate-resources phase we must first make sure we invoke keytool:clean otherwise we get an error from keytool that the specified alias already exists. So we can add the following to our POM:

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>keytool-maven-plugin</artifactId>
  <executions>
    <execution>
      <phase>generate-resources</phase>
      <id>clean</id>
      <goals>
        <goal>clean</goal>
      </goals>
    </execution>
    <execution>
      <phase>generate-resources</phase>
      <id>generateKeyPair</id>
      <goals>
        <goal>generateKeyPair</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <keystore>${project.build.directory}/jetty-ssl.keystore</keystore>
    <dname>CN=BioCreative, OU=NLM, O=NIH, L=Bethesda, ST=DC</dname>
    <keypass>jetty6</keypass>
    <storepass>jetty6</storepass>
    <alias>jetty6</alias>
    <keyalg>RSA</keyalg>
  </configuration>
</plugin>

Now we can invoke mvn jetty:run and the keystore is automatically generated and used by the Jetty plugin.

Configuring Tomcat

Tomcat Authentication

To deploy the WAR file into Tomcat is a bit difficult then Jetty. First we need to add an user with roles manager-gui and manager-script. In %TOMCAT_PATH%/conf/tomcat-users.xml


<tomcat-users>
  <role rolename="manager-gui"/>
  <role rolename="manager-script"/>
  <user username="admin" password="password" 
    roles="manager-gui,manager-script" />
</tomcat-users>

Maven Authentication

Add above Tomcat’s user in the Maven setting file %MAVEN_PATH%/conf/settings.xml, later Maven will use this user to login Tomcat server.


<settings ...>
  <servers>
    <server>
      <id>TomcatServer</id>
      <username>admin</username>
      <password>password</password>
    </server>
  </servers>
</settings>

Tomcat Maven Plugin

Declares a Maven Tomcat plugin in pom.xml

<plugin>
  <groupId>org.apache.tomcat.maven</groupId>
  <artifactId>tomcat7-maven-plugin</artifactId>
  <version>2.2</version>
  <configuration>
    <url>http://localhost:8080/</url>
    <server>TomcatServer</server>
    <path>/biocreative</path>
  </configuration>
</plugin>

During deployment, it tells Maven to deploy the WAR file to Tomcat server via http://localhost:8080/, on path /biocreative, using “TomcatServer” (in settings.xml) username and password for authentication.

Deploy to Tomcat

Commands to manipulate WAR file on Tomcat.

  • mvn tomcat7:deploy
  • mvn tomcat7:undeploy
  • mvn tomcat7:redeploy

For example,

mvn tomcat7:deploy

Tomcat 6 Example

If you use Tomcat 6, change the plugin artifactId in pom.xml to tomcat6-maven-plugin. The commend line could be

  • mvn tomcat6:deploy
  • mvn tomcat6:undeploy
  • mvn tomcat6:redeploy
]]>
https://blog.pengyifan.com/how-to-create-a-web-application-project-with-javamavenjetty/feed/ 2
How to collect Immutable Collection in Java https://blog.pengyifan.com/how-to-collect-immutable-collection-in-java/ https://blog.pengyifan.com/how-to-collect-immutable-collection-in-java/#respond Fri, 17 Apr 2015 14:53:06 +0000 http://blog.pengyifan.com/?p=729 Read More »]]> To begin with this story, let’s first have a look at how to creat a List from Stream in Java

List<String> sublist = list
  .stream()
  .filter(...)
  .collect(Collectors.toList());

This works perfectly fine but what if we want the list to be immutable? We could do this

List<String> immutableSubList = Collections.unmodifiableList(sublist);

or if we would like to use Guava ImmutableList, we could do

ImmutableList<String> immutableSubList = ImmutableList.copyOf(sublist);

However this is a bit awkward to use since the list will be copied one more time. If we want to do this in a lot of places throughout the code base, it is not fluid. Instead, what we want is

ImmutableList<String> sublist = list
  .stream()
  .filter(...)
  .collect(ImmutableCollectors.toList());

This post will discuss how to create the Collector of ImmutableList.

Collector

To create a Collector, we will use the static method of.

public static<t, A, R> Collector<T, A, R> of(
  Supplier<A> supplier,
  BiConsumer<A, T> accumulator,
  BinaryOperator<A> combiner,
  Function<A, R> finisher,
  Characteristics... characteristics);

Here’s a short explaination of the parameters

  • The supplier returns the resulting object that will be populated by the collector.
  • The accumulator adds an element from the stream into the list created by the supplier.
  • The combiner combines two list instances into one. This function is called by the collector when the stream is in parallel mode.
  • The characteristics provides hints to the Collector how it can optimize reduction implementations. We leave it blank here.

Collect ImmutableList

  public static <T> Collector<T, ?, ImmutableList<T>> toList() {
    return Collector.of(
        ImmutableList.Builder::new,
        ImmutableList.Builder::add,
        (left, right) -> left.addAll(right.build()),
        (Function<ImmutableList.Builder<T>, ImmutableList<T>>)
            ImmutableList.Builder::build);
  }

The implementation uses the Collector.of method. I use

  • ImmutableList.Builder::new to create a supplier.
  • ImmutableList.Builder::add to add elements from the stream into the builder.
  • The combiner function combines the results of two different supplier instances (created when the stream is in parallel mode). So if we have two builders, we can combine them by calling the addAll method, then return the left builder.
  • ImmutableList.Builder::build to build the ImmutableList.

Collect ImmutableSet

Similarly, we can create immutable set

  public static <T> Collector<T, ?, ImmutableSet<T>> toSet() {
    return Collector.of(
        ImmutableSet.Builder::new, 
        ImmutableSet.Builder::add, 
        (left, right) -> left.addAll(right.build()), 
        (Function<ImmutableSet.Builder<T>, ImmutableSet<T>>)
            ImmutableSet.Builder::build,
        Collector.Characteristics.UNORDERED);
  }

Here, I use Collector.Characteristics.UNORDERED to indicate that the collection operation does not commit to preserving the encounter order of input elements.

Test cases

  @Test
  public void test_toList() {
    List<String> list = Lists.newArrayList("a", "b");
    ImmutableList<String> sublist = list
        .stream()
        .filter(s -> s.charAt(0) == 'a')
        .collect(ImmutableCollectors.toList());
    assertTrue(Iterables.getOnlyElement(sublist).equals("a"));
  }
  
  @Test
  public void test_toSet() {
    List<String> list = Lists.newArrayList("a", "b");
    ImmutableSet<String> subset = list
        .stream()
        .filter(s -> s.charAt(0) == 'a')
        .collect(ImmutableCollectors.toSet());
    assertTrue(Iterables.getOnlyElement(subset).equals("a"));
  }

Conclusion

The full code can be found at ImmutableCollectors in the library of pengyifan-commons.

<repositories>
    <repository>
        <id>oss-sonatype</id>
        <name>oss-sonatype</name>
        <url>https://oss.sonatype.org/content/repositories/snapshots/</url>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
    </repository>
</repositories>
...
<dependency>
  <groupId>com.pengyifan</groupId>
  <artifactId>pengyifan-commons</artifactId>
  <version>0.1.0-SNAPSHOT</version>
</dependency>
]]>
https://blog.pengyifan.com/how-to-collect-immutable-collection-in-java/feed/ 0