使用Maven构建Web项目

参考 http://blog.csdn.net/yuguiyang1990/article/details/8796410

1.新建Maven项目

1.1 File -> New -> Other

1365863541_5385

1.2 选择Maven Project ,单击Next

1365863553_1351

1.3 保持默认即可,单击Next

1365863566_6467

1.4 选择Archetype为 web app,单击Next

1365863577_7171

1.5 输入一些必要信息,单击Finish

1365863587_8509

1.6 项目结构如下图:

1365863599_9491

或者如下图

在Mac下面的Eclipse Kepler中目录的位置有所变化

screenshot

2.配置项目(某些修改实际工作中用不到,以下仅供参考

现在开始修改一些配置

2.1 在项目上右键单击,添加Source Folder

Maven的项目有一些约定:src/main/java , src/main/resources , src/test/java , src/test/resources .那么,添加这些文件夹:(注意,创建文件夹有可能失败,比如Kepler 上面,此时,到目录下面直接创建文件夹然后刷新Eclipse项目就可以了

1365863613_2412

输入Source Folder 的名字

1365863628_6400

创建完之后的目录结构:

1365863640_6524

2.2 修改Build Path 配置

在项目上,右键单击,选择 Build Path ->Configure Build Path

1365863656_2376

选择 Source标签,会显示4个Source Folder ,修改他们的 OutPut folder :

1365863670_3566

双击每个文件夹的Output folder,选择路径

src/main/java,src/main/resources,选择target /classes;
src/test/java ,src/test/resources, 选择target/test-classes;

1365863682_6273

修改完成后如下图所示:

1365863693_6468

修改JDK版本:选择 libraries 标签,选中JRE library,单击Edit按钮

1365863704_4952

选择系统默认的就可以了,单击 Finish 按钮:

1365863729_2512

最后,单击OK即可:

1365863769_4461

完成后,项目结构如下图:

1365863781_4158

2.3 将项目转换为Dynamic Web Project

在项目上右键单击,选择 Properties:

1365863806_5537

在左侧选择 Project Facets,单击右侧的 ”Convert faceted from “链接:

1365863817_6166

修改Java为你当前项目的JDK,并添加Dynamic Web Module ,最后单击”Further Configuration available“ 链接:

1365863830_6294

修改Content directory 为 src/main/webapp ,单击OK:

1365863840_2584

在一次单击OK,完成操作:

1365863853_7859

2.4 设置部署程序集(Web Deployment Assembly)

在项目上右键单击,选择Properties,在左侧选择Deployment Assembly

1365863864_8268

此处列表是,部署项目时,文件发布的路径。
1,我们删除test的两项,因为test是测试使用,并不需要部署。
2,设置将Maven的jar包发布到lib下。
Add -> Java Build Path Entries -> Maven Dependencies -> Finish
设置完成效果图
1365863878_5803

单击OK

完成后,项目结构如下图所示:

1365863887_1279

就这样,使用Maven构建的一个Web项目就完成了。

Eclipse debugger always blocks on ThreadPoolExecutor without any obvious exception

I'm working on my usual projects on Eclipse, it'a a J2EE app, made with Spring, Hibernate and so on. I'm using tomcat7 for this (no particular reason, I don't exploit any new feature, I just wanted to try that). Every time I debug my application, it happens that eclipse debugger pops out like it has reached a breakpoint, but it is not the case, in fact it stops on a Java Source File that is ThreadPoolExecutor. There is no stack trace on the console, it just stops. Then if I click on resume it goes on and the app works perfectly. This is what shows in the debugger window:

Daemon Thread ["http-bio-8080"-exec-2] (Suspended (exception RuntimeException))
ThreadPoolExecutor$Worker.run() line: 912
TaskThread(Thread).run() line: 619

I really can't explain this, because I'm not using ThreadPoolExecutor at all. Must be something from Tomcat, Hibernate or spring. It's very annoying because I always have to resume during debugging.

Any clues?

The posted stack trace indicates that a RuntimeException was encountered in a Daemon thread. This is typically uncaught at runtime, unless the original developer caught and handled the exception.

Typically, the debugger in Eclipse is configured to suspend execution at the location where the exception was thrown, on all uncaught exceptions. Note that the exception might be handled later, lower down in the stack frame and might not lead to the thread being terminated. This would be cause of the behavior observed.

Configuring the behavior of Eclipse is straightforward - in the Preferences Dialog, the Debug pane under Java in the tree hierarchy, has the option titled "Suspend execution on uncaught exceptions", which can be unchecked.

junit4入门例子

第一步:eclipse中新建一个项目,java build path中导入junit jar包(本文例子junit-4.9b1.jar)

第二步:新建一个package,导入如下四个文件

第三步:右键AllCalculatorTests(或者CalculatorTest、SquareTest),run as junit test,查看执行结果。

代码中的注释能够帮你理解Junit4。

package andycpp;

public class Calculator {
private static int result; // 静态变量,用于存储运行结果
public void add(int n) {
result = result + n;
}
public void substract(int n) {
result = result - 1; //Bug: 正确的应该是 result =result-n
}
public void multiply(int n){
} // 此方法尚未写好
public void divide(int n) {
result = result / n;
}
public void square(int n) {
result = n * n;
}
public void squareRoot(int n) {
for (;  ;) ; //Bug : 死循环
}
public void clear() { // 将结果清零
result = 0;
}
public int getResult() {
return result;
}
}

 

package andycpp;
/*
* import static,这是一个静态包含(static),是JDK5中新增添的一个功能。也就是说,assertEquals是Assert类中的一系列的静态方法,
* 一般的使用方式是Assert. assertEquals(),但是使用了静态包含后,前面的类名就可以省略了,使用起来更加的方便
* */
import static org.junit.Assert.*;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
//测试类名称任意

public class CalculatorTest {
//你要测试哪个类,那么你首先就要创建一个该类的对象
private static Calculator calculator = new Calculator();
/*
* @Before和@After是每个测试方法执行前后均需要执行,
* 因此不适合累中耗资源,或者耗时过大的操作。
* @BeforeClass 和 @AfterClass两个Fixture来帮规避此问题。
* 从名字上就可以看出,用这两个Fixture标注的函数,只在测试用例
* 初始化时执行 @BeforeClass方法,当所有测试执行完毕之后,执行
* @AfterClass进行收尾工作。在这里要注意一下,每个测试类只能有
* 一个方法被标注为 @BeforeClass 或 @AfterClass,
* 并且该方法必须是Public和Static的
* */
@BeforeClass
public static void setUpBeforeClass() throws Exception {
}

@AfterClass
public static void tearDownAfterClass() throws Exception {
}
/*
* 我们非常希望每一个测试都是独立的,相互之间没有任何耦合度。
* 因此,我们就很有必要在执行每一个测试之前,对Calculator对象进行一个“复原”操作,
* 以消除其他测试造成的影响。因此,“在任何一个测试执行之前必须执行的代码”就是一个Fixture,
* 我们用@Before来标注它 这里不在需要@Test标注*
* */
@Before
public void setUp() throws Exception {
calculator.clear();
}

@After
public void tearDown() throws Exception {
}
//@Test 标准的方法,返回值必须是void,而且无参数
@Test
public void testAdd() {
calculator.add(2);
calculator.add(3);
assertEquals(5,calculator.getResult());//第一个参数填写期待结果,第二个参数填写实际结果

}

@Test
public void testSubstract() {
calculator.add(10);
calculator.substract(2);
assertEquals(8,calculator.getResult());
}
/*
* 如果你已经把该方法的测试用例写完,但该方法尚未完成,那么测试的时候一定是“失败”。
* 这种失败和真正的失败是有区别的,因此JUnit提供了一种方法来区别他们,那就是在这种
* 测试函数的前面加上@Ignore标注,这个标注的含义就是“某些方法尚未完成,暂不参与此次测试”。
* 这样的话测试结果就会提示你有几个测试被忽略,而不是失败。一旦你完成了相应函数,只需要把@Ignore标注删去,
* 就可以进行正常的测试。
* */
@Ignore
@Test
public void testMultiply() {
calculator.add(2);
calculator.multiply(3);
assertEquals(6,calculator.getResult());
}

@Test
public void testDivide() {
calculator.add(8);
calculator.divide(2);
assertEquals(4, calculator.getResult());
}
/*
* 对于那些逻辑很复杂,循环嵌套比较深的程序,
* 很有可能出现死循环,因此一定要采取一些预防措 施。
* 限时测试是一个很好的解决方案。我们给这些测试函数设定
* 一个执行时间,超过了这个时间,他们就会被系统强行终止,
* 并且系统还会向你汇报该函数结束的原 因是因为超时,这样你就可以发现这些Bug了
* 测试例子calculator中的squareRoot是个死循环。
* */
@Test(timeout = 1000)//单位为毫秒
public void squareRoot() {
calculator.squareRoot(4);
assertEquals(2, calculator.getResult());
}
/*使用@Test标注的expected属性,将我们要检验的异常传递给他,
* 这样JUnit框架就能自动帮我们检测是否抛出了我们指定的异常
* */
@Test(expected = ArithmeticException.class)
public void divideByZero() {
calculator.divide(0);
}
}
package andycpp;

import java.util.Arrays;
import java.util.Collection;
import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

/*
* 对于参数测试需要重新写一个类, 而不能与其他测试共用同一个类,此例中我们定义了一个SquareTest类。
* 然后,你要为这个类指定一个 Runner,而不能使用默认的Runner了,因为特殊的功能要用特殊的Runner嘛。
* @RunWith(Parameterized.class)
*
* */
@RunWith(Parameterized.class)
public class SquareTest {
private static Calculator calculator = new Calculator();
private int param;
private int result;
/*
* 定义测试数据的集合,也就是上述的data()方法,
* 该方法可以任意命名,但是必须使用@Parameters标注进行修饰。
* 这个方法的框架就不予解释了,大家只需要注意其中的数据,是一个二维数组,
* 数据两两一组,每组中的这两个数据,一个是参数,一个是你预期的结果
* */
@Parameters
public static Collection date(){
return Arrays.asList(new Object[][]{
{2, 4},
{0, 0},
{-3, 9},
});
}

//构造函数,对变量进行初始化

//定义一个待测试的类,并且定义两个变量,一个用于存放参数,一个用于存放期待的结果。
public SquareTest(int param, int result) {
this.param = param;
this.result = result;
}

@Test
public void square() {
calculator.square(param);
assertEquals(result, calculator.getResult());
}

}

 

package andycpp;
import org.junit.runner.RunWith;

import org.junit.runners.Suite;

/*
* 大家可以看到,这个功能也需要使用一个特殊的Runner,
* 因此我们需要向@RunWith标注传递一个参数Suite.class。
* 同时,我们还需要另外一个标注@Suite.SuiteClasses,
* 来表明这个类是一个打包测试类。我们把需要打包的类作为参数传递给该标注就可以了。
* 有了这两个标注之后,就已经完整的表达了所有的含义,因此下面的类已经无关紧要,
* 随便起一个类名,内容全部为空既可
* */
@RunWith(Suite.class)

@Suite.SuiteClasses({

CalculatorTest.class,

SquareTest.class

})
public class AllCalculatorTests {

}

 

一个简单的Jsp+Servlet实例

开发环境Eclipse+Tomcat7

1、先创建web project,项目名为Hello,

2、在WebRoot 目录下创建login.jsp文件,只需修改body中的内容,如下所示:

<body>
   <form action="login">
   username:<input type="text" name="username"><br>
   password:<input type="password" name="pwd"><br>
   <input type="submit">
   </form>
 </body>

3、在scr目录下的com.ht.servlet编写AcountBean.java文件,代码如下:

package com.ht.servlet;

public class AccountBean {
private String username = "";
private String password = "";
public String getPassword() {
 return password;
}
public void setPassword(String password) {
 this.password = password;
}
public String getUsername() {
 return username;
}
public void setUsername(String username) {
 this.username = username;
}
}

4、在scr目录下的com.ht.servlet编写servlet类CheckAccount.java文件,代码如下:

package com.ht.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class CheckAccount extends HttpServlet {

 @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
  throws ServletException, IOException {
 doGet(req,resp);
 }

 @Override
public void doGet(HttpServletRequest req, HttpServletResponse resp)
  throws ServletException, IOException {
 HttpSession session = req.getSession();
  AccountBean account = new AccountBean();
  String username = req.getParameter("username");
 String pwd = req.getParameter("pwd");
  account.setPassword(pwd);
 account.setUsername(username);
  if((username != null)&&(username.trim().equals("jsp"))) {
  if((pwd != null)&&(pwd.trim().equals("1"))) {
   System.out.println("success");
   session.setAttribute("account", account);
    String login_suc = "success.jsp";
   resp.sendRedirect(login_suc);
    return;
  }
 }
 String login_fail = "fail.jsp";
 resp.sendRedirect(login_fail);
  return;
}

}

5、在WebRoot目录下编写success.jsp文件 成功后跳转

<body>
   <%
   AccountBean account = (AccountBean)session.getAttribute("account");
    %>
   username:<%= account.getUsername()%>
    <br>
    password:<%= account.getPassword() %>
 </body>

6、在WebRoot目录下编写fail.jsp文件 失败后跳转

<body>
  Login Failed! <br>
 </body>

7、修改web.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
 <welcome-file-list>
   <welcome-file>login.jsp</welcome-file>
 </welcome-file-list>

 <servlet>
      <description>This is the description of my J2EE component</description>
      <display-name>This is the display name of my J2EE component</display-name>
        <servlet-name>CheckAccount</servlet-name>
      <servlet-class>com.ht.servlet.CheckAccount</servlet-class>
    </servlet>

     <servlet-mapping>
      <servlet-name>CheckAccount</servlet-name>
      <url-pattern>/login</url-pattern>
    </servlet-mapping>

</web-app>

Eclipse add Tomcat 7 blank server name

I was trying to add Tomcat 7 in my Eclipse in Ubuntu. When I click "Add new server" in Eclipse and select "Tomcat v7.0 Server", the field "Server Name" is blank and I cannot type in anything in that textbox as shown below:

0pHnn

It is a bug in Eclipse. I had exactly the same problem, also on Ubuntu with Eclipse Java EE Juno.

Here is the workaround that worked for me:

1.Close Eclipse
2.In {workspace-directory}/.metadata/.plugins/org.eclipse.core.runtime/.settings delete the following two files:
org.eclipse.wst.server.core.prefs
org.eclipse.jst.server.tomcat.core.prefs
3.Restart Eclipse

Tomcat在Mac平台安裝

到http://tomcat.apache.org下載tomcat版,例如apache-tomcat-7.0.42.tar.gz
将apache-tomcat-7.0.42.tar.gz 解压缩到目标目录
执行

 chmod a+x apache-tomcat-7.0.42/bin/*.sh

设置管理用户密码:
编辑 apache-tomcat-7.0.42/conf/tomcat-users.xml , 加入

<role rolename="manager-gui"/>
<user username="User" password="password" roles="manager-gui"/>

設定好後執行 apache-tomcat-7.0.42/bin/startup.sh , 再使用browser連到http://localhost:8080, 如果可以看到以下画面, Tomcat Server的安裝算是初步完成

Apache Tomcat_7.0.42_Default_Page

設定Launchd主要讓Mac OS X server啟動時, 也順便啟動Tomcat Server, Launchd有點類似Windows的NT Service使用Launchd來啟動Tomcat Server

1.到 apache-tomcat-7.0.42/bin/目錄下新增一個檔案 launchd_wrapper.sh, 內容如下

#!/bin/bash
function shutdown()
{
date
echo "Shutting down Tomcat"
$CATALINA_HOME/bin/catalina.sh stop
}
date
echo "Starting Tomcat Server"
export CATALINA_PID=/tmp/$$
# Uncomment to increase Tomcat's maximum heap allocation
# export JAVA_OPTS=-Xmx512M $JAVA_OPTS
export JAVA_OPTS="-Xms256m -Xmx512m -XX:MaxPermSize=256m"
export CATALINA_OPTS="-DHUDSON_HOME=/Users/admin/hudson"
. $CATALINA_HOME/bin/catalina.sh start
# Allow any signal which would kill a process to stop Tomcat
trap shutdown HUP INT QUIT ABRT KILL ALRM TERM TSTP

请注意 ,launchd_wrapper.sh要使用

chmod a+x launchd_wrapper.sh

使其具有执行权限

2. 加入tomcat for Launchd 文件, 到/Library/LaunchDaemons目录使用

 sudo touch tomcat.plist

新增tomcat.plist

3. 使用

sudo vi tomcat.plist

, 编辑tomcat.plist, 文件內容如下, 要注意的是/Users/admin为安装目录, 请改成你的目录

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"><dict><key>Disabled</key>
<false/><key>EnvironmentVariables</key><dict><key>CATALINA_HOME</key>
<string>/Users/admin/Library/apache-tomcat-7.0.42</string>
<key>JAVA_HOME</key>
<string>/Library/Java/Home</string>
</dict>
<key>Label</key>
<string>com.apache.tomcat</string>
<key>OnDemand</key>
<false/>
<key>ProgramArguments</key>
<array>
<string>/Users/admin/Library/apache-tomcat-7.0.42/bin/launchd_wrapper.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>ServiceDescription</key>
<string>Tomcat</string>
<key>StandardErrorPath</key>
<string>/Users/admin/apache-tomcat-7.0.42/logs/launchd.stderr</string>
<key>StandardOutPath</key>
<string>/Users/admin/apache-tomcat-7.0.42/logs/launchd.stdout</string>
<key>UserName</key>
<string>root</string>
</dict>
</plist>

4.手动测试Launchd

sudo launchctl load -w /Library/LauhchDaemons/tomcat.plist

停止指令

sudo launchctl unload -w /Library/LaunchDaemons/tomcat.plist

测试OK后, 下次重新开机Tomcat Server就会自己执行了.

处理在64位Ubuntu使用jd-gui报错error while loading shared libraries: libgtk-x11-2.0.so.0

在64位Ubuntu中使用jd-gui反编译时出现错误:
error while loading shared libraries: libgtk-x11-2.0.so.0

此时,需要安装如下依赖包,即可:

(Ubuntu 13.04 x64)

$ sudo apt-get install ia32-libs-gtk libglib2.0-dev

(Ubuntu 13.10 x64)

$ sudo apt-get install libgtk2.0-0:i386 libxxf86vm1:i386 libsm6:i386 libglib2.0-dev libcanberra-gtk-module:i386 gtk2-engines-murrine:i386