Java 项目Building之后发现的Blocker和Critical

     刚来公司老大吩咐我做Code Quality. 需要做到所有的项目的Blocker 和 Critical 的数量为0.当时我觉得很难,因为我已经没有做个Java项目,所以面对这些Issue有点害怕,毕竟我的改动会造成整个项目的问题。当时就连一个空格老大都严格的要求我,格式有一点点的错误老大就回reject的提交的代码。。。。。。一把辛酸泪啊!想想刚来的时候神马Jekins,神马Jira,神马Sonar简直了!!!

    我遇到Issue主要包括:

—              1.Badpractice        定义equals却没有定义hashCode
—              2.Dodgy                  从实例方法里直接修改类变量,即static属性
—              3.Performance      HashMapentrySetiterator  inseadof keySet  iterator
—              4.Correctness       空指针被引用,或者没有检查指针是否为null

    我依稀记得我当时做的第一个Blocker就是,项目中出现最多的问题    “Catch Exception instead of Throwable”  这是一个很普遍的错误。

       catch (Exception t) {

       Log.logError(getClass(),"Error Collecting Metrics", t);

  }

      catch(Throwablet){

       Log.logError(getClass(),"Error Collecting Metrics", t);

  }

 原因: Throwable 包括了Exception 和 error ,catch 的只是Exception, error 是不需要的catch的,如果catch有可能造成很严重的后果。

—2. Use a logger to log this exception

        

`        This exceptionwill often get logged in a separate file (System.err) making debugging more complex than itneeds

—3.“equals(Object obj)”should be overridden along with thecompareTo(T obj)” method

       “equals(Object obj)”  and  “hashCode()“  shouldbe overridden in pairsBadPractice

     这两个问题其实很深奥,必须了解hashMap的存储机制,后续我会详细解释,记住一点hashCode相同equals不一定相同。

下面介绍的都是Critical的问题, Critical是

—1.Method may fail to close stream

try {

  InputStreaminputStream =null;

  inputStream= new FileInputStream(downloadFile);

  byte[]buffer = new byte[BUFFER_SIZE];

  intbytesRead =-1;

  while((bytesRead= inputStream.read(buffer))!= -1) {

  output.write(buffer,0, bytesRead);

  }

} catch(Exception e) {

  thrownew WebApplicationException(e);

}


try (InputStreaminput = newFileInputStream(downloadFile)){

  byte[]buffer = new byte[BUFFER_SIZE];

  intbytesRead =-1;

  while ((bytesRead= input.read(buffer))!= -1) {

  output.write(buffer,0, bytesRead);

            }

}catch (Exception e) {

        throw new WebApplicationException(e);

}


如果把stream在try的括号里面初始化就可以保证stream最后一定会被close


—2.Equalitytests should not be made withfloating point values

  if (OPEN_FILE_COUNT== 0.00 || CONFIG_VALUE == 0.00)

  if (OPEN_FILE_COUNT== 0L || CONFIG_VALUE == 0L)

原因:计算机表示实数的精度问题

—
—3.makes inefficient use of keySetiterator instead of entrySetiterator

for(Integer index : this.clients.keySet()){

  Zclientc = this.clients.get(index);

—

    Map<Integer,ZClient> mapSet= this.clients; 

   for (Map.Entry<Integer,ZClient>entry : mapSet.entrySet()){

  Integerindex = entry.getKey();

  ZClientc = entry.getValue();

原因:提高效率,因为EntrySet 会比keySet访问的次数减少一次。

—4.In J2EEgetClassLoader() might not work as expected. UseThreadcurrentThread() getContextClassLoader() instead.

     在动态加载资源的时候如果使用class.getClassLoader(),可能会导致和当前线程所运行的类和加载器不一致

这个问题没有实质性的理解。。。。。。。


—5.Synchronizethis lazy initialization of 'streamInstance

        private staticStreamDatastreamInstance= null;

    public static StreamDatagetStreamInstance(){

           if (streamInstance== null) {

         streamInstance= new StreamData();

            }

             return streamInstance;

       }

       privatestatic StreamDatastreamInstance= new StreamData();

       publicstatic StreamDatagetStreamInstance(){

                return streamInstance;

      }

后续将在单例模式中详细的解释

—6. Possiblenull pointer dereference of null (Correctness)

     if (dir.isDirectory()){

            String[]children = dir.list();

            for (Stringchild : children) {

                  return traverse(newFile(dir,child));

           }

     

—   

    if (dir.isDirectory()){

          String[]children = dir.list();

          if(children !=null){

                 for (Stringchild : children) {

                        return traverse(newFile(dir,child));

                 }

          }

   }

很简单不解释


—7. Use"object == null" instead of "object.equals(null)" to test for nullity toprevent null pointer exceptions

  if (null!= reqHead&& !reqHead.equals(null))

  if (null!= reqHead)

—8.Returning 'ruleName'may exposean internal array

   代码使一个指向外部多个对象的引用指向了一个内部对象存储地址

   privateString[] ruleName;

   publicString[] getName() {

                String[]temp = ruleName;

            return temp;

  }

  public void setName(String[]name) {

           String[] temp = name;

           this.ruleName= temp;

  }

—9. Useless Operation On Immutable

           String是一个不可变类,调用String上的任何操作都会返回新的String对象,虽然String是一个class,但实际上对它的任何操作都可以把它看成基本数据类型,比如s.trim方法是不会改变s值。

  Stringtext = null;

   while ((text = reader.readLine())!= null) {

    lineNumber++;

    text.trim();

text = text.trim();

—10.Method invokes inefficient new String(String) constructor(Performance)

  Integer portNumber= null;

  if (port!= null) {

  portNumber= new Integer((int)port.intValue());}

 

     portNumber= Integer.valueOf(port.intValue());

—11.Callto equals() comparing different types(Correctness)

      if (disabled.equals(true)){

  log.info("NucleonExtension Framework is disabled...");

  return;

    }

 

     if (disabled.equals("true"))

—12.BUG: Write to static field frominstance method
—BUG描述:This instance method writes to a staticfield. This is tricky to get correct if multiple instances are beingmanipulated, and generally bad practice.(实例方法直接写静态变量。)
—问题原因:sInstance是类的静态成员变量,非静态方法直接对其赋值,非静态方法是与对象相关联的,当多个对象同时对该变量进行赋值时可能出现问题。

 

—解决方法:在使用静态成员变量时使用getset方法。



发布了144 篇原创文章 · 获赞 238 · 访问量 26万+
展开阅读全文

启动sonar后自动stopping

12-15

2017.12.15 10:14:15 INFO app[][o.s.a.AppFileSystem] Cleaning or creating temp directory /home/sonar/sonarqube-6.2/temp 2017.12.15 10:14:15 INFO app[][o.s.p.m.JavaProcessLauncher] Launch process[es]: /data/android/jdk/jdk1.8.0_151/jre/bin/java -Djava.awt.headless=true -Xmx1G -Xms256m -Xss256k -Djna.nosys=true -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -XX:+HeapDumpOnOutOfMemoryError -Djava.io.tmpdir=/home/sonar/sonarqube-6.2/temp -javaagent:/data/android/jdk/jdk1.8.0_151/jre/lib/management-agent.jar -cp ./lib/common/*:./lib/search/* org.sonar.search.SearchServer /home/sonar/sonarqube-6.2/temp/sq-process5065419232036463929properties 2017.12.15 10:14:23 INFO app[][o.s.p.m.Monitor] Process[es] is up 2017.12.15 10:14:23 INFO app[][o.s.p.m.JavaProcessLauncher] Launch process[web]: /data/android/jdk/jdk1.8.0_151/jre/bin/java -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djruby.management.enabled=false -Djruby.compile.invokedynamic=false -Xmx512m -Xms128m -XX:+HeapDumpOnOutOfMemoryError -Djava.io.tmpdir=/home/sonar/sonarqube-6.2/temp -javaagent:/data/android/jdk/jdk1.8.0_151/jre/lib/management-agent.jar -cp ./lib/common/*:./lib/server/*:/home/sonar/sonarqube-6.2/lib/jdbc/mysql/mysql-connector-java-5.1.39.jar org.sonar.server.app.WebServer /home/sonar/sonarqube-6.2/temp/sq-process9006207429545419068properties 2017.12.15 10:14:24 INFO app[][o.s.p.m.Monitor] Process[es] is stopping 2017.12.15 10:14:24 ERROR app[][o.s.p.m.Monitor] Process[web] failed to start 2017.12.15 10:14:24 INFO app[][o.s.p.m.Monitor] Process[es] is stopped <-- Wrapper Stopped 问答

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览