关于The APR based Apache Tomcat Native library警告

2017年9月1日 由 Creater 没有评论 »

今天在Eclipse上配置Tomcat8,启动时看到如下警告信息:

The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path

感到很不舒服,于是在网上找了些解决办法。

 

以下内容来自:http://cooliron.blog.163.com/blog/static/124703138201112211571276/

 

在eclipse中,启动tomcat时会出现如此信息:The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path,它其实不影响程序的正常运行,但看到了,感觉实在别扭。其解决办法如下:

http://archive.apache.org/dist/tomcat/tomcat-connectors/native/下载tcnative-1.dll,然后放到你的JDK路径下的bin目录下。重新启动tomcat,就没有问题了。

这个tcnative-1.dll 他的作用如下:

tomcat整合本地apr会使效率提升:
一是,处理静态资源的时候速度更快,(注:有人用jmeter,对使用apr前后的tomcat进行压力测试,结果显示,性能是有一定的提升,但是没有想象中多,只有一点点,当然,这与运行的逻辑有关,但是我个人认为在大多数情况下这部分性能提升甚微)。
二是,我认为提升比较多的是对ssl的处理效率,当tomcat处理https的请求是,如果使用本地的openssl库,肯定会比前面提升的效率高。(虽然没有实际测试数据,但我推测这里的性能提升比例上要比第一点多得多)。

 

原因上面已经说得很清楚了,下面说下我的解决办法。

首先,tcnative-1.dll不需要下载,至少对于Tomcat7来说是这样,我们可以在其bin目录下找到这个dll;

其次,tcnative-1.dll放在哪儿不要紧,只要在系统的PATH中可以找到就行。

 

解决:

在系统的环境变量中添加CATALINA_HOME,它指向你的Tomcat根目录,接着在PATH路径中添加%CATALINA_HOME%\bin;

这样就可以解决了,对了,设置完成后,可能需要重启下Eclipse。

Tomcat启动时org.apache.catalina.startup.VersionLoggerListener. INFO

2017年9月1日 由 Creater 没有评论 »

解决办法:

打开Tomcat安装后目录,进入conf文件夹,找到配置文件server.xml,将注释掉。
817863-20161012191816703-608550536

PDF Expert破解版_注册码_注册机_激活码无限期使用

2017年8月20日 由 Creater 没有评论 »

版权归作者所有,任何形式转载请联系作者。
作者:缘来远去(来自豆瓣)
来源:https://www.douban.com/note/629052203/

当它的时间来编辑,所有你需要伟大的工具,很容易找到,只需点击即可。PDF Expert的快速注解,方便填写表格,以及强大的文件合并将通过咀嚼你在最短的时间工作。
PDF Expert mac破解版_注册码_注册机_激活码

下载地址:
http://dwz.cn/6i8jeq
http://dwz.cn/6i8jeq
http://dwz.cn/6i8jeq
http://dwz.cn/6i8jeq
另附cleanmymac4破解版下载
https://www.douban.com/note/612586476/
NTFS for mac 破解版链接
https://www.douban.com/note/625295363/

版权归作者所有,任何形式转载请联系作者。
作者:缘来远去(来自豆瓣)
来源:https://www.douban.com/note/629052203/

注册码:
1118-1517-2860-1380-6669-1696
3203-2497-1391-9945-1283-5110
0071-5043-3014-7690-8454-9945

Apache FTPClient操作“卡死”问题的分析和解决

2017年8月16日 由 Creater 没有评论 »

在部署到生产环境之后发现FTP操作不规律性出现“卡死”现象:程序捕获不到任何异常一直卡着,导致轮巡无法正常工作。

为了解决这个问题,首先考虑的是对于FTPClient的使用上没有设置超时时间,于是设置了ConnectTimeout、DataTimeout、DefaultTimeout后在生产环境上继续观察,但是问题依旧没有解决。后来我有些怀疑FTPClient api本身是不是有什么问题,想实在不行自己实现一个超时机制吧,不过还是不甘心,还是想从FTPClient api本身去解决问题。又经过一翻研究之后发现:需要使用被动模式,以下摘抄别人的一段简单描述:
在项目中使用commons-net-3.0.1.jar实现FTP文件的下载,在windows xp上运行正常,但是放到linux上,却出现问题,程序运行到 FTPClient.listFiles()或者FTPClient.retrieveFile()方法时,就停止在那里,什么反应都没有,出现假死状态。google一把,发现很多人也出现了此类问题,最终在一个帖子里找到了解决办法。在调用这两个方法之前,调用FTPClient.enterLocalPassiveMode();这个方法的意思就是每次数据连接之前,ftp client告诉ftp server开通一个端口来传输数据。为什么要这样做呢,因为ftp server可能每次开启不同的端口来传输数据,但是在linux上,由于安全限制,可能某些端口没有开启,所以就出现阻塞。OK,问题解决。

于是我回滚了之前的修改,改为被动模式。但是问题依旧。于是能想到的就是最有的绝招:实在不行自己实现一个超时机制吧。经过一翻研究最简单的方式就是使用:Future解决:

public static void main(String[] args) throws InterruptedException, ExecutionException {
        final ExecutorService exec = Executors.newFixedThreadPool(1);

        Callable<String> call = new Callable<String>() {
            public String call() throws Exception {
                Thread.sleep(1000 * 5);
                return "线程执行完成.";
            }
        };

        try {
            Future<String> future = exec.submit(call);
            String obj = future.get(4 * 1000, TimeUnit.MILLISECONDS); // 任务处理超时时间设置
            System.out.println("任务成功返回:" + obj);
        } catch (TimeoutException ex) {
            System.out.println("处理超时啦....");
            ex.printStackTrace();
        } catch (Exception e) {
            System.out.println("处理失败.");
            e.printStackTrace();
        }
        // 关闭线程池
        exec.shutdown();
        
        System.out.println("完毕");
    }

当然了还有很多其他方式:
http://tech.sina.com.cn/s/2008-07-04/1051720260.shtml
http://itindex.net/blog/2010/08/11/1281486125717.html
http://darkmasky.iteye.com/blog/1115047
http://www.cnblogs.com/wasp520/archive/2012/07/06/2580101.html
http://coolxing.iteye.com/blog/1476289
http://www.cnblogs.com/chenying99/archive/2012/10/24/2737924.html
虽然找到了终极的“必杀技”,但是此时我还是不甘心,还是想从FTPClient api本身去解决问题,但此时看来也别无它他法。只能试试:即设置被动模式又设置超时时间。经过实际测试,发现问题得以解决。下面把我的FTP工具类贴给大家分享,希望能帮到遇到同样问题的人。

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

public class FtpUtil {
    public static final String ANONYMOUS_LOGIN = "anonymous";
    private FTPClient ftp;
    private boolean is_connected;

    public FtpUtil() {
        ftp = new FTPClient();
        is_connected = false;
    }
    
    public FtpUtil(int defaultTimeoutSecond, int connectTimeoutSecond, int dataTimeoutSecond){
        ftp = new FTPClient();
        is_connected = false;
        
        ftp.setDefaultTimeout(defaultTimeoutSecond * 1000);
        ftp.setConnectTimeout(connectTimeoutSecond * 1000);
        ftp.setDataTimeout(dataTimeoutSecond * 1000);
    }

    /**
     * Connects to FTP server.
     * 
     * @param host
     *            FTP server address or name
     * @param port
     *            FTP server port
     * @param user
     *            user name
     * @param password
     *            user password
     * @param isTextMode
     *            text / binary mode switch
     * @throws IOException
     *             on I/O errors
     */
    public void connect(String host, int port, String user, String password, boolean isTextMode) throws IOException {
        // Connect to server.
        try {
            ftp.connect(host, port);
        } catch (UnknownHostException ex) {
            throw new IOException("Can't find FTP server '" + host + "'");
        }

        // Check rsponse after connection attempt.
        int reply = ftp.getReplyCode();
        if (!FTPReply.isPositiveCompletion(reply)) {
            disconnect();
            throw new IOException("Can't connect to server '" + host + "'");
        }

        if (user == "") {
            user = ANONYMOUS_LOGIN;
        }

        // Login.
        if (!ftp.login(user, password)) {
            is_connected = false;
            disconnect();
            throw new IOException("Can't login to server '" + host + "'");
        } else {
            is_connected = true;
        }

        // Set data transfer mode.
        if (isTextMode) {
            ftp.setFileType(FTP.ASCII_FILE_TYPE);
        } else {
            ftp.setFileType(FTP.BINARY_FILE_TYPE);
        }
    }

    /**
     * Uploads the file to the FTP server.
     * 
     * @param ftpFileName
     *            server file name (with absolute path)
     * @param localFile
     *            local file to upload
     * @throws IOException
     *             on I/O errors
     */
    public void upload(String ftpFileName, File localFile) throws IOException {
        // File check.
        if (!localFile.exists()) {
            throw new IOException("Can't upload '" + localFile.getAbsolutePath() + "'. This file doesn't exist.");
        }

        // Upload.
        InputStream in = null;
        try {

            // Use passive mode to pass firewalls.
            ftp.enterLocalPassiveMode();

            in = new BufferedInputStream(new FileInputStream(localFile));
            if (!ftp.storeFile(ftpFileName, in)) {
                throw new IOException("Can't upload file '" + ftpFileName + "' to FTP server. Check FTP permissions and path.");
            }

        } finally {
            try {
                in.close();
            } catch (IOException ex) {
            }
        }
    }

    /**
     * Downloads the file from the FTP server.
     * 
     * @param ftpFileName
     *            server file name (with absolute path)
     * @param localFile
     *            local file to download into
     * @throws IOException
     *             on I/O errors
     */
    public void download(String ftpFileName, File localFile) throws IOException {
        // Download.
        OutputStream out = null;
        try {
            // Use passive mode to pass firewalls.
            ftp.enterLocalPassiveMode();

            // Get file info.
            FTPFile[] fileInfoArray = ftp.listFiles(ftpFileName);
            if (fileInfoArray == null) {
                throw new FileNotFoundException("File " + ftpFileName + " was not found on FTP server.");
            }

            // Check file size.
            FTPFile fileInfo = fileInfoArray[0];
            long size = fileInfo.getSize();
            if (size > Integer.MAX_VALUE) {
                throw new IOException("File " + ftpFileName + " is too large.");
            }

            // Download file.
            out = new BufferedOutputStream(new FileOutputStream(localFile));
            if (!ftp.retrieveFile(ftpFileName, out)) {
                throw new IOException("Error loading file " + ftpFileName + " from FTP server. Check FTP permissions and path.");
            }

            out.flush();
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException ex) {
                }
            }
        }
    }

    /**
     * Removes the file from the FTP server.
     * 
     * @param ftpFileName
     *            server file name (with absolute path)
     * @throws IOException
     *             on I/O errors
     */
    public void remove(String ftpFileName) throws IOException {
        if (!ftp.deleteFile(ftpFileName)) {
            throw new IOException("Can't remove file '" + ftpFileName + "' from FTP server.");
        }
    }

    /**
     * Lists the files in the given FTP directory.
     * 
     * @param filePath
     *            absolute path on the server
     * @return files relative names list
     * @throws IOException
     *             on I/O errors
     */
    public List<String> list(String filePath) throws IOException {
        List<String> fileList = new ArrayList<String>();
        
        // Use passive mode to pass firewalls.
        ftp.enterLocalPassiveMode();
        
        FTPFile[] ftpFiles = ftp.listFiles(filePath);
        int size = (ftpFiles == null) ? 0 : ftpFiles.length;
        for (int i = 0; i < size; i++) {
            FTPFile ftpFile = ftpFiles[i];
            if (ftpFile.isFile()) {
                fileList.add(ftpFile.getName());
            }
        }
        
        return fileList;
    }

    /**
     * Sends an FTP Server site specific command
     * 
     * @param args
     *            site command arguments
     * @throws IOException
     *             on I/O errors
     */
    public void sendSiteCommand(String args) throws IOException {
        if (ftp.isConnected()) {
            try {
                ftp.sendSiteCommand(args);
            } catch (IOException ex) {
            }
        }
    }

    /**
     * Disconnects from the FTP server
     * 
     * @throws IOException
     *             on I/O errors
     */
    public void disconnect() throws IOException {

        if (ftp.isConnected()) {
            try {
                ftp.logout();
                ftp.disconnect();
                is_connected = false;
            } catch (IOException ex) {
            }
        }
    }

    /**
     * Makes the full name of the file on the FTP server by joining its path and
     * the local file name.
     * 
     * @param ftpPath
     *            file path on the server
     * @param localFile
     *            local file
     * @return full name of the file on the FTP server
     */
    public String makeFTPFileName(String ftpPath, File localFile) {
        if (ftpPath == "") {
            return localFile.getName();
        } else {
            String path = ftpPath.trim();
            if (path.charAt(path.length() - 1) != '/') {
                path = path + "/";
            }

            return path + localFile.getName();
        }
    }

    /**
     * Test coonection to ftp server
     * 
     * @return true, if connected
     */
    public boolean isConnected() {
        return is_connected;
    }

    /**
     * Get current directory on ftp server
     * 
     * @return current directory
     */
    public String getWorkingDirectory() {
        if (!is_connected) {
            return "";
        }

        try {
            return ftp.printWorkingDirectory();
        } catch (IOException e) {
        }

        return "";
    }

    /**
     * Set working directory on ftp server
     * 
     * @param dir
     *            new working directory
     * @return true, if working directory changed
     */
    public boolean setWorkingDirectory(String dir) {
        if (!is_connected) {
            return false;
        }

        try {
            return ftp.changeWorkingDirectory(dir);
        } catch (IOException e) {
        }

        return false;
    }

    /**
     * Change working directory on ftp server to parent directory
     * 
     * @return true, if working directory changed
     */
    public boolean setParentDirectory() {
        if (!is_connected) {
            return false;
        }

        try {
            return ftp.changeToParentDirectory();
        } catch (IOException e) {
        }

        return false;
    }

    /**
     * Get parent directory name on ftp server
     * 
     * @return parent directory
     */
    public String getParentDirectory() {
        if (!is_connected) {
            return "";
        }

        String w = getWorkingDirectory();
        setParentDirectory();
        String p = getWorkingDirectory();
        setWorkingDirectory(w);

        return p;
    }

    /**
     * Get directory contents on ftp server
     * 
     * @param filePath
     *            directory
     * @return list of FTPFileInfo structures
     * @throws IOException
     */
    public List<FfpFileInfo> listFiles(String filePath) throws IOException {
        List<FfpFileInfo> fileList = new ArrayList<FfpFileInfo>();
        
        // Use passive mode to pass firewalls.
        ftp.enterLocalPassiveMode();
        FTPFile[] ftpFiles = ftp.listFiles(filePath);
        int size = (ftpFiles == null) ? 0 : ftpFiles.length;
        for (int i = 0; i < size; i++) {
            FTPFile ftpFile = ftpFiles[i];
            FfpFileInfo fi = new FfpFileInfo();
            fi.setName(ftpFile.getName());
            fi.setSize(ftpFile.getSize());
            fi.setTimestamp(ftpFile.getTimestamp());
            fi.setType(ftpFile.isDirectory());
            fileList.add(fi);
        }

        return fileList;
    }

    /**
     * Get file from ftp server into given output stream
     * 
     * @param ftpFileName
     *            file name on ftp server
     * @param out
     *            OutputStream
     * @throws IOException
     */
    public void getFile(String ftpFileName, OutputStream out) throws IOException {
        try {
            // Use passive mode to pass firewalls.
            ftp.enterLocalPassiveMode();
            
            // Get file info.
            FTPFile[] fileInfoArray = ftp.listFiles(ftpFileName);
            if (fileInfoArray == null) {
                throw new FileNotFoundException("File '" + ftpFileName + "' was not found on FTP server.");
            }

            // Check file size.
            FTPFile fileInfo = fileInfoArray[0];
            long size = fileInfo.getSize();
            if (size > Integer.MAX_VALUE) {
                throw new IOException("File '" + ftpFileName + "' is too large.");
            }

            // Download file.
            if (!ftp.retrieveFile(ftpFileName, out)) {
                throw new IOException("Error loading file '" + ftpFileName + "' from FTP server. Check FTP permissions and path.");
            }

            out.flush();

        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException ex) {
                }
            }
        }
    }

    /**
     * Put file on ftp server from given input stream
     * 
     * @param ftpFileName
     *            file name on ftp server
     * @param in
     *            InputStream
     * @throws IOException
     */
    public void putFile(String ftpFileName, InputStream in) throws IOException {
        try {
            // Use passive mode to pass firewalls.
            ftp.enterLocalPassiveMode();
            
            if (!ftp.storeFile(ftpFileName, in)) {
                throw new IOException("Can't upload file '" + ftpFileName + "' to FTP server. Check FTP permissions and path.");
            }
        } finally {
            try {
                in.close();
            } catch (IOException ex) {
            }
        }
    }
}

commons2.0FTP组件开发上传时间过长程序假死解决方案

2017年8月14日 由 Creater 没有评论 »

最近使用apache上面的commons 2.0开发ftp使用过程中,因为涉及到大文件的长时间传输,在最后经常导致程序死掉。其中传文件的代码如下:

/** 
 * 上传文件到服务器,新上传和断点续传 
 * @param remoteFile 远程文件名,在上传之前已经将服务器工作目录做了改变 
 * @param localFile 本地文件File句柄,绝对路径 
 * @param processStep 需要显示的处理进度步进值 
 * @param ftpClient FTPClient引用 
 * @return 
 * @throws IOException 
 */  
public boolean uploadFile(String remoteFile,File localFile,FTPClient ftpClient,long remoteSize) throws IOException{  
    boolean status;  
    //显示进度的上传  
    long step = localFile.length() / 100;  
    long process = 0;  
    long localreadbytes = 0L;  
    RandomAccessFile raf = new RandomAccessFile(localFile,"r");  
    OutputStream out = ftpClient.appendFileStream(new String(remoteFile.getBytes("GBK"),"iso-8859-1"));  
    //断点续传设置起始位置  
    if(remoteSize>0){  
        ftpClient.setRestartOffset(remoteSize);  
        process = remoteSize /step;  
        raf.seek(remoteSize);  
        localreadbytes = remoteSize;  
    }  
    byte[] bytes = new byte[1024];  
    int c;  
    //开始上传  
    while((c = raf.read(bytes))!= -1){  
        out.write(bytes,0,c);  
        localreadbytes+=c;  
        if(localreadbytes / step != process){  
            process = localreadbytes / step;  
//          System.out.println("上传进度:" + process);  
            //TODO 添加汇报上传状态内容  
        }  
    }  
    logger.info("清空输出流");  
    out.flush();  
    logger.info("关闭文件读句柄");  
    raf.close();  
    logger.info("关闭输出流");  
    out.close();  
    logger.info("关闭输出流成功");  
    boolean status = ftpClient.completePendingCommand();  
    logger.info("从上传方法返回");  
    return status;  
}  

如果上传大的文件,比如说是500M文件,ftp传输大概需要两个小时左右的时候,ftpClient.completePendingCommand()方法就会死掉,我在网上也查了一些内容,说是打开的流必须关闭后ftp Server才会返回正确的状态吗。问题是我关闭了同样没有收到正确的状态码。

如果换成appendFile(String remoteFile,InputStream in)这种方法就不会存在问题,

问题在于completePendingCommand()方法始终不能返回,介绍一下我在调试过程中遇到的问题。
1.FTP服务器有控制连接和数据连接,我的猜测是在进行数据传输的过程中,数据连接一直工作,但是控制连接可能就处于空闲状态,造成被服务器主动关闭,因此不能正常返回。
2.在网上也看了一些网友的介绍,说在调用completePendingCommand()方法时必须关闭输入输出流,而调用这个方法主要就是为了拿到服务器端的226相应(File OK)。
3.我的方法再调用completePendingCommand()方法时,输入输出流确实已经关闭,所以上诉的第2点不适合我的程序。
4.另外我对程序进行更改,不调用completePendingCommand()方法,直接返回 后,发现在后续的程序中,如果发送命令(如PASV)到服务器端,收到的响应为226 File receive OK.而后续的基本上都正常了。

综合以上分析我采用如下的方法来处理:
在关闭输入输出流后发送NOOP命令激活控制连接,然后调用completePendingCommand()方法返回。
现在我测试的结果是,即使数据传输3个小时,也不会造成程序假死。

while((c = raf.read(bytes))!= -1){  
    out.write(bytes,0,c);  
    localreadbytes+=c;  
    if(localreadbytes / step != process){  
        process = localreadbytes / step;  
//      System.out.println("上传进度:" + process);  
        //汇报上传状态,汇报进度函数,自己实现  
        reportUploadPercent((int)process);  
    }  
    out.flush();  
}  
raf.close();  
out.close();  
ftpClient.sendNoOp();  
boolean result = ftpClient.completePendingCommand();  

VS 用户自定义控件未出现在工具箱的解决方案

2017年7月27日 由 Creater 没有评论 »

在项目中增加几个用户自定义控件,想及时在窗口Form上添加时却发现工具箱根本就没有这些用户自定义控件,研究了很久,发现有两个解决办法。通过以下两种方法操作后,再重新编译,在工具箱上就会出现用户自定义控件了,项目中所有的自定义控件都会及时显示到工具箱上。
【1】工具=》选项=》Windows窗体设计器=》常规=》AutoToolBoxPopulate=》True

12

【2】项目=》刷新项目工具箱

3

旧版Office 2016 for Mac 64位安装

2017年7月24日 由 Creater 没有评论 »

1.卸载:
https://support.office.com/zh-cn/article/通过在重新安装之前完全卸载来解决-Office-2016-for-Mac-问题-ec3aa66e-6a76-451f-9d35-cba2e14e94c0
2.安装
Office 2016 for Mac 64位
版本号:15.36 (170702)
大小:1.66G
微软官方下载地址:
https://officecdn-microsoft-com.akamaized.net/pr/C1297A47-86C4-4C1F-97FA-950631F94777/OfficeMac/Microsoft_Office_2016_15.36.17070200_Installer.pkg

激活方法——安装好Office后,点击Mac系统屏幕最上方Finder右侧的“前往”、“电脑”,再依次打开“Macintosh HD”、“资源库”,将授权文件拷贝到“Preferences”文件夹里,即可完成激活。注:Office for Mac 2016的账号登录,跟激活无关,用户可直接跳过正常使用。
com.microsoft.office.licensingv2.plist

关掉Spotlight

2017年7月24日 由 Creater 没有评论 »

1、在终端执行:sudo mdutil -a -i off。
2、将我的数据文件(100GB左右大量小文件)列入隐私,排除在外。
3、恢复时执行:sudo mdutil -a -i on