系统找不到名为HelloWorldApp的类文件。一般地,该错误意味着类名拼写和源文件名不一样,系统创建filename.class文件时使用的是类定义的名字,并且区分大小写。
例如:
经编译后将创建HelloWorldapp.class类。执行时,也要使用这个名字。发生这个错误时,可以使用文件查看命令Is或dir看看当前目录下是否存在相应的文件,并检查文件名的大小写。
2.错误提示内容:InclassHelloWorldApp:mainmustbepublicandstatic
解释:如果main()方法的左侧缺少static或public,会发生这个错误。前面已经解释过对main()方法前面的修饰符有特殊的要求。
3.文件中含有的类个数错误
解释:按照Java规则,在一个源文件中最多只能定义一个公有类,否则会发生运行时错误。如果一个应用系统中有多个公有类,则要把它们分别放在各自不同的文件中。文件中非公有类的个数不限。
4.层次错误
(1)一个包说明,即package语句,包说明是可选的。
(2)任意多个引入语句,即import语句。
(3)类和接口说明。
这些语句必须按一定的次序出现,即,引入语句必须出现在所有的类说明之前,如果使用了包说明,则它必须出现在类说明和引入语句之前。
例如,下面是正确的语句序列:
packageTransportation;
importjaya.awt.Graphics
importjays.applet.Applet;
下面是两例错误的语句顺序:
importjava.aWt.Graphics
importjava.applet.Applet;
该例中在包说明语句之前含有其他语句。
packageHouse;
解释:(当键入javaHelloWorldApp时发生该错误。)
该例中含有两个包说明语句。
classA{StringgetPath(){returnthis.getClass().getClassLoader().getSystemResource("A").getPath();}}
2。取出类ClassLoader的开始路径(执行路径)//StringpreUri=this.getClass().getClassLoader().getResource("").getPath();
比如WebApp的项目,以下的指令得出的结果就是
/D:/project/crFj163Web/web/exploded/WEB-INF/classes/
比如你是纯java的程序,就是你执行java指令的当前路径
3。取出jdk所在的bin目录
其中user.dir是一个参数,更多参数请看这里
二、jsp/servlet中的取路径
以前我们常用getRealPath(),不过这个方法已经不推荐用了。但我们可以使用request.getContextPath().另外还有request.getRequestURL()或者request.getRequestURI()。下面举例,以建立一个app1的webapp为例
1。request.getContextPath()打印出来的是
/app1
2。request.getRequestURL()打印出来的是
3。request.getRequestURI()打印出来的是
/app1/index.jsp
首先我们来看看Java程序的反加密,也就是通常所说的Crack过程,只有明白了这个过程,我们才能有效的对我们的程序进行加密。
通常我们得到的Java程序的Crack包有两种,一种属于KeyGen(注册码生成器)、一种属于替换修改;
这种办法只适合对付只要一个注册号,别的什么都不要的情况,经典代表BorlandJBuilder&OptimizeitSuite
再看第二种,为什么要用替换修改?我们是修改了那部分呢?不用想,肯定是License验证的部分,为什么我们不像上面的方法那样找加密算法呢?原因有两种:(1)使用上面的办法搞不定;(2)Java程序不仅要Key,还有其他的License配置;遇到这种情况,我们只要找到用于License验证的类,进行修改替换就行了。
这种办法使用于任何情况,经典代表BEAWebLogic
经过上面的分析,我们的问题就集中了,关键就是怎么找到用于License验证的部分或加密算法的部分,我们需要3个工具:一个是Sun公司提供的标准JVM:),一个是你的耐心和细心:),一个是Jad(经典Java反编译工具)。
我们可以看见这个文件里面有好多熟悉的东西啊:java.*/com.sun.*/javax.*等等,但这个不是我们关心的,我们要的是com.togethersoft.*或者是一些没有包名的zd.d等等。(这里插一句,几乎所有的Java应用程序都会混淆的,其实混淆的原理也很简单,我们后面再说。)先找找有没有License有关的,Serach一下,嘿嘿,果然,474行:com.togethersoft.together.impl.ide.license.LicenseSetup.execute([DashoPro-V2-050200]:Unknownline),Ok上那堆classpath中的Jar包里面找一下吧(推荐用WinRAR),找到了之后用Jad反编译,一看,这个没有混淆,但是用了一个zae的类,这个看名字就知道混淆过了,先不理它,再看看下面一句IdeLicenseAccess.setLicense(zae1),Ok接着找到IdeLicenseAccess,哈哈,就这点名堂,所有的License验证都是走的这个类,面向对象的思想不错,呵呵:)
就这样,一个Java应用程序搞定了。看看其实也很简单。
再回过头来说说Java程序的加密;从上面的两种方法来看,Java程序似乎是没有什么完美的办法进行加密的,其实不然,我们必须遵循一些原则,才能有效的保护你的产品。
原则一,尽量使用公钥和秘钥对进行加密;原则二,不要在加密验证的部分使用面向对象思想:)把验证的方法写在程序的各个角落,并标注为privatefinalvoid,让编译器替你处理成内联方法;原则三,尽可能的大幅度混淆:)找个好点的混淆器
下面代码中用到的sourceImage是一个已经存在的Image对象
图像剪切对于一个已经存在的Image对象,要得到它的一个局部图像,可以使用下面的步骤:
//importjava.awt.*;//importjava.awt.image.*;ImagecroppedImage;ImageFiltercropFilter;CropFilter=newCropImageFilter(25,30,75,75);//四个参数分别为图像起点坐标和宽高,即CropImageFilter(intx,inty,intwidth,intheight),详细情况请参考APICroppedImage=Toolkit.getDefaultToolkit().createImage(newFilteredImageSource(sourceImage.getSource(),cropFilter));
如果是在Component的子类中使用,可以将上面的Toolkit.getDefaultToolkit().去掉。FilteredImageSource是一个ImageProducer对象。图像缩放对于一个已经存在的Image对象,得到它的一个缩放的Image对象可以使用Image的getScaledInstance方法:
ImagescaledImage=sourceImage.getScaledInstance(100,100,Image.SCALE_DEFAULT);//得到一个100X100的图像ImagedoubledImage=sourceImage.getScaledInstance(sourceImage.getWidth(this)*2,sourceImage.getHeight(this)*2,Image.SCALE_DEFAULT);//得到一个放大两倍的图像,这个程序一般在一个swing的组件中使用,而类Jcomponent实现了图像观察者接口ImageObserver,所有可以使用this。//其它情况请参考API
灰度变换下面的程序使用三种方法对一个彩色图像进行灰度变换,变换的效果都不一样。一般而言,灰度变换的算法是将象素的三个颜色分量使用R*0.3+G*0.59+B*0.11得到灰度值,然后将之赋值给红绿蓝,这样颜色取得的效果就是灰度的。另一种就是取红绿蓝三色中的最大值作为灰度值。java核心包也有一种算法,但是没有看源代码,不知道具体算法是什么样的,效果和上述不同。
publicGrayModel(ColorModelsourceModel){super(sourceModel.getPixelSize());this.sourceModel=sourceModel;modelStyle=0;}
publicGrayModel(ColorModelsourceModel,intstyle){super(sourceModel.getPixelSize());this.sourceModel=sourceModel;modelStyle=style;}
publicvoidsetGrayStyle(intstyle){modelStyle=style;}
protectedintgetGrayLevel(intpixel){if(modelStyle==CS_MAX){returnMath.max(sourceModel.getRed(pixel),Math.max(sourceModel.getGreen(pixel),sourceModel.getBlue(pixel)));}elseif(modelStyle==CS_FLOAT){return(int)(sourceModel.getRed(pixel)*0.3+sourceModel.getGreen(pixel)*0.59+sourceModel.getBlue(pixel)*0.11);}else{return0;}}
publicintgetAlpha(intpixel){returnsourceModel.getAlpha(pixel);}
publicintgetRed(intpixel){returngetGrayLevel(pixel);}
publicintgetGreen(intpixel){returngetGrayLevel(pixel);}
publicintgetBlue(intpixel){returngetGrayLevel(pixel);}
publicintgetRGB(intpixel){intgray=getGrayLevel(pixel);return(getAlpha(pixel)<<24)+(gray<<16)+(gray<<8)+gray;}}
如果你有自己的算法或者想取得特殊的效果,你可以修改类GrayModel的方法getGrayLevel()。色彩变换根据上面的原理,我们也可以实现色彩变换,这样的效果就很多了。下面是一个反转变换的例子:
publicintgetRed(intpixel){return~sourceModel.getRed(pixel);}
publicintgetGreen(intpixel){return~sourceModel.getGreen(pixel);}
publicintgetBlue(intpixel){return~sourceModel.getBlue(pixel);}
publicvoidsetColorModel(ColorModelcm){substituteColorModel(cm,newReverseColorModel(cm));}
publicintfilterRGB(intx,inty,intpixel){returnpixel;}}
要想取得自己的效果,需要修改ReverseColorModel.java中的三个方法,getRed、getGreen、getBlue。下面是上面的效果的一个总的演示程序。
publicGrayImage(){ii=newImageIcon(\"images/11.gif\");source=ii.getImage();iw=source.getWidth(this);ih=source.getHeight(this);filter=newGrayFilter();filter2=newGrayFilter(GrayModel.CS_FLOAT);gray=createImage(newFilteredImageSource(source.getSource(),filter));gray3=createImage(newFilteredImageSource(source.getSource(),filter2));cropFilter=newCropImageFilter(5,5,iw-5,ih-5);clip=createImage(newFilteredImageSource(source.getSource(),cropFilter));bigimg=source.getScaledInstance(iw*2,ih*2,Image.SCALE_DEFAULT);MediaTrackermt=newMediaTracker(this);mt.addImage(gray,0);try{mt.waitForAll();}catch(Exceptione){}}
publicvoidpaint(Graphicsg){Graphics2Dg2=(Graphics2D)g;bimg=newBufferedImage(iw,ih,BufferedImage.TYPE_INT_RGB);Graphics2DsrcG=bimg.createGraphics();RenderingHintsrhs=g2.getRenderingHints();srcG.setRenderingHints(rhs);srcG.drawImage(source,0,0,null);ColorSpacegraySpace=ColorSpace.getInstance(ColorSpace.CS_GRAY);