今年初,Google Guice和SpringSource宣布将合作提出一套标准的用于依赖注入的注解,即JSR-330。但这些注解与JSR-299却并不一致,随后引发了众多的争论,不过现在一切都已经尘埃落定:JSR-299采用了JSR-330的注解,两者都将成为Java EE 6的一部分。

有不少人针对JSR-299与JSR-330的冲突谈到了自己的一些看法,列举如下:

* Gavin King:我认为引入另一套语义上与299相同的注解完全是个错误,而且其尝试解决的问题也与299大同小异。
* Bob Lee: 虽然299对于那些小型的Java EE应用来说很适合,但其全局配置以及不直接的天性使之很难适应于数百万代码行的应用,就像Google所开发的。我们能够在Guice上轻松支持299 风格的注解,但却无法通过299实现Guice的全部功能,因此没有理由放弃Guice而转向299。就我个人来说,我认为你们在299上已经进行了不少的创新,但却没有完全理解用户代码是需要维护的这个事实。
* Alex Miller:向JSR 299领域进军是个危险的信号。
* Antonio Goncalves:我希望我们不要打响一个新的战役,就像Java Module(JSR 277)和Modularity Support(JSR 294)之间那样。
* Rickard Öberg说出了反对意见:相对于泛泛的使用@Inject这样的注解,我们选择使用能代表目标对象范围的注解,因为什么都是也意味着什么都不是。

JSR-330已经通过了JSR评审的投票,但众多投票者都强调了两个规范的和谐相处:

* Sun:我们希望该JSR能与JSR-299共同努力以便为SE和EE平台达成一个一致、全面的依赖注入标准。这个标准务必先于该JSR的公共预览版发布前形成。
* Red Hat:我们认识到该草案是有社区支持的,因此打算在专家组发布公共草案时再发表最终意见。如果该JSR与JSR-299之间能达成某种一致(这种一致性会为依赖注入定义一种轻量级的模型),那我们会毫不犹豫地投出赞成票。Red Hat承诺会为这种一致性贡献自己的一份绵薄之力。
* Ericsson:我们支持为标准化Java SE的依赖注入所付出的努力,但更想强调的是保持与JSR 299的一致性对于Java SE和EE都是非常重要的。
* IBM:我们也认为这样一份描述SE应用的依赖注入规范是很有必要的,然而所提出的注入模式却与EE平台中的定义有出入。SE/EE的注入模型必须要形成一个单独可扩展的编程模型:为SE定义一套核心功能并通过EE的功能对其进行扩展。因此,要是不统一的话,IBM是不会支持JSR 299或是330的。
* Oracle: 虽然支持该JSR,但Oracle严重关注该草案的完整性及其与JSR 299的分歧,因为这可能会导致平台的分裂。因此,我们期望在该JSR的公共预览版发布前能与JSR 299达成一致。我们相信JSR 250的一个修订或是维护版会比较适合发布依赖注入相关的注解。最终我们希望这种一致性的努力会让SE和EE平台的依赖注入保持一致,形成一个标准化的机制以满足各种需求。

目前这些规范之间的冲突已经得到解决。JSR-330(面向Java的依赖注入)以及JSR-299(面向Java EE平台的上下文与依赖注入)已经达成一致了,后者将采取前者的注解,两者都将成为Java EE6的一部分。迄今为止,社区的反响还是积极的(Matt Corey、Jeremy Norris、Alex Miller、Oliver Gierki、Niklas Gustavsson)。(CSDN)

Posted on August 24, 2009 5:35 PM | | Comments (0) | TrackBacks (0)

Groovy创始人James Strachan前日在其博客上发表了一篇文章,题目为《Scala将取代Java /javac?》。以下是正文部分的翻译:

Groovy

不要误解我的意思——我在过去的这十来年里写了无数的Java代码,并且坚信它相对C++和Smalltalk来说是一个巨大的进步(当然,很多其它语言也很有帮助,像JavaScript,Ruby,Groovy,Python等)。但是我还是一直期待着能有javac的替代者出现。我甚至还自创了一门语言(编者注:此处指Groovy)好让我暂时满足一下这种期望。

Java是一种令人惊叹的复杂语言(它的语法规范长达600 页,我怀疑到底有没有人能真正理解它),它有自动装箱(Autoboxing),空指针异常(NPE)往往就是这时抛出的。其中的基本类型 (primitive type),字符串/文字/缓冲器/集合类(collections)以及数组缺乏多态性,以至于处理任何数据结构都需要冗长的语法;而且,由于Bean 属性和对闭包支持的缺失(甚至在JDK 7里也仍然还不支持),这会让你的代码里充满了 try/catch/finally 这些语句(除非你使用框架和新的自定义API)。除了这些还有好多数不清的麻烦问题。Java倒是有类型推断(type inference)功能但却不用,使得我们要多输/读如此大量的代码。

这个问题在没有Java7后变得更加紧迫 (在Snorcle之后它变得更加重要:我不知道javac是不是要被jdkc 取而代之了?)。所以我猜javac可能已经走到了尽头,它看起来根本就没有什么进展或简化了。

那么,从长久来看,谁能取代java呢?当然,像Ruby,Groovy,Python,还有JavaScript这些动态语言在过去几年里很受欢迎——很多人喜欢他们。

我认为将来可能替代javac的就是Scala 。它实在太让我印象深刻了。我甚至可以诚实地说,如果有人在2003年把Martin Odersky,Lex Spoon以及Bill Venners写的那本《Programming in Scala》拿给我看了的话,那我根本就不会再去发明Groovy了。

那么,为什么我会看好Scala呢?Scala是静态类型的,它可以被编译成与Java同样快速的字节码,所以它的速度与Java不分上下(有时快一点,有时慢一点)。你可以看看 Scala 在与 groovy 或jruby一起进行测试时表现有多好。注意:速度并不是我们追求的唯一目标——有时候我们可能宁肯让代码慢上十倍,也要写得简洁一点;但是如果要取代 javac,速度当然还是很重要的。(CSDN)

Posted on August 11, 2009 12:45 PM | | Comments (0) | TrackBacks (0)

Google%20App%20Engine.png
Google has announced that it has added Java to Python as the supported languages on its App Engine service. Adding Java was the first and most popular request from developers and users that was filed in App Engine's issue tracker. App Engine launched with only Python support with an App Engine API added to access the shared database and other functionality. For the Java implementation, Google has wrapped the App Engine APIs with appropriate Java standards, such as the Java Servlet API, JDO and JPA, javax.cache and javax.mail.

The runtime also provides a secure sandbox for applications and Google notes that this sandbox may create issues for some Java code. The company is giving the first 10,000 interested developers early access to the Java language support, aiming to get feedback on the sandbox and other compatibility issues.

To support Java developers, Google announced that the Google Plugin For Eclipse will support App Engine alongside the Google Web Toolkit, and will allow applications to be developed using GWT running on App Engine or using either GWT or App Engine alone.

Google also announced it has added policy controlled access to data behind a firewall, database import support and task scheduling with a Cron like mechanism. The scheduling feature does not actually run processes, but allows developers to set up specific URLs within their App Engine application to be queried at regular intervals. (Via The H)

Posted on July 23, 2009 3:49 PM | | Comments (0) | TrackBacks (0)

the Alfresco CMS is one of the most flexible and powerful CMS platforms available on the market today. Powered by J2EE technology, Alfresco CMS can be seamlessly integrated into your IT infrastructure. Some of the highlights of Alfresco CMS:

* Powerful Enterprise Features
* Highly Scalable Java Technology
* Built in Web 2.0
* No license fees

Alfresco CMS features an advanced content management backend, which can be customised to suit the business and operational needs of your organisation.

Alfresco CMS

Posted on July 21, 2009 1:59 PM | | Comments (0) | TrackBacks (0)

Release Notes - Maven 2 - Version 2.2.0

** Sub-task
* [MNG-4144] - document escape character for curly braces in clear-text passwords for settings.xml password security
* [MNG-4145] - switch to released versions of plexus-sec-dispatcher (and by ext. plexus-cipher) once they're available

** Bug
* [MNG-2258] - Wrong execution order of plugins in same phase
* [MNG-3401] - Plugin parameters must be specified outside an execution block when they are invoked from the command line
* [MNG-3553] - cannot resolve dependency with scope import
* [MNG-3776] - Namespace misspelled in settings.xml
* [MNG-4074] - cyclic reference with 2.1.0-RC1 that doesn't occur with 2.0.10
* [MNG-4082] - Encryption is triggered if passwords merely contain curly braces
* [MNG-4126] - [regression] Properties defined in profiles.xml of parent are not inherited during multimodule build
* [MNG-4137] - NPE in DefaultLIfecycleExecutor when run from within Hudson builds
* [MNG-4140] - Properties incorrectly replaced in pom
* [MNG-4146] - password security doesn't work with custom password providers
* [MNG-4147] - very long passwords cause LightweightHTTP wagon to line-wrap the Base64-encoded Authorization header
* [MNG-4165] - http session cookies rejected with non-lightweight http wagon (maybe with lightweight one too)
* [MNG-4166] - Problem parsing command-line options in release:perform
* [MNG-4167] - version-expression transformation interferes with plugins like GPG
* [MNG-4168] - String index out of range: 43807
* [MNG-4179] - [regression] Artifact download hangs upon transfer failure
* [MNG-4184] - [regression] maven2.1 fails with cyclic dependency in case of extension/dependency for report-plugin to reactor-project
* [MNG-4207] - Plugins that use ArtifactResolver with http repositories AND depend on log4j run into ExceptionInInitializerError
* [MNG-4213] - preemptive auth in non-lightweight http wagon causes Unauthorized responses from some servers
* [MNG-4219] - update plexus-utils to avoid leaking processes in CommandLineUtils.getSystemEnvars()

** Improvement
* [MNG-2979] - Cross module dependencies for multi-module site
* [MNG-3203] - maven should execute compiler:compile and :test-compile in separate executions, to allow separate configuration
* [MNG-3834] - Improve error message when dependency with classifier is missing version
* [MNG-4210] - Remove log4j configuration warning

** Task
* [MNG-4143] - Update Java requirement to 1.5
* [MNG-4169] - Remove invocation of maven-plugin-plugin:updatePluginRegistry from default lifecycle bindings

** Wish
* [MNG-4139] - avoid the schema location in generated maven-metadata*.xml

Download:http://www.apache.org/dyn/closer.cgi/maven/binaries/apache-maven-2.2.0-bin.zip
More:http://maven.apache.org/download.html

Posted on July 5, 2009 7:57 PM | | Comments (0) | TrackBacks (0)

先分折HTML代码,取得SRC地扯,假设本地图片地扯存在,先填冲到HTML当中,,把假设的数据和远程的地扯保存在数据库中, 然后用线程池的方式,去读数据库中地扯下载, 这个只能在JVM起动了,就可以调用下载功能.

Java代码

1. create table CMS_IMAGES
2. (
3. id LONG PRIMARY KEY, --id
4. wsrc varchar2(256),--远程图片地扯
5. lsrc varchar2(256),--本地图片地扯
6. state NUMBER, --此图片的状态 1未处理 2下载中 3下载失败
7. last_modified LONG --上次状态修改时间
8. modified_count number--状态修改次数-缺省为0
9. )
10. 先解释一下, 3下载失败了,等两个小时,重新通线程调用一次,因为有的网站,不能让你老是在他的网站上面下载图片的,只有过些时间再请求一次,就可以下载,实在不能下载的图片,比率很小,
11.
12.
13. /**
14. * 下载图片的后台线程池
15. * @author
16. * @version 1.0
17. */
18.
19.
20. public class ThreadPoolManager {
21. protected static Logger log = LoggerFactory
22. .getLogger(ThreadPoolManager.class);
23.
24. private static ThreadPoolManager tpm = new ThreadPoolManager();
25.
26. // 线程池维护线程的最少数量
27. private final static int CORE_POOL_SIZE = 4;
28.
29. // 线程池维护线程的最大数量
30. private final static int MAX_POOL_SIZE = 10;
31.
32. // 线程池维护线程所允许的空闲时间
33. private final static int KEEP_ALIVE_TIME = 0;
34.
35. // 线程池所使用的缓冲队列大小
36. private final static int WORK_QUEUE_SIZE = 10;
37.
38. // 图片缓冲队列
39. private Queue msgQueue = new LinkedList();
40.
41. // 访问消息缓存的调度线程
42. final Runnable accessBufferThread = new Runnable() {
43. public void run() {
44. // 查看是否有待定请求,如果有,则创建一个新的Thread,并添加到线程池中
45. if (hasMoreAcquire()) {
46. ImageDO image = (ImageDO) msgQueue.poll();
47. Runnable task = new UploadThread(image);
48. threadPool.execute(task);
49. }
50.
51. if (hasImagesInDB()) {
52. try {
53. BeanFactoryService beanFactory = (BeanFactoryService) BizServiceManager
54. .getInstance().getService(
55. BeanFactoryService.SERVICE_NAME);
56. ImageManager imageManager = (ImageManager) beanFactory
57. .getBean("imageManager");
58. List images = imageManager
59. .getImages(ImageDO.STATE_READY);
60. for (int i = 0; i < images.size(); i++) {
61. ImageDO img = images.get(i);
62. img.setState(ImageDO.STATE_RUNNING);
63. img.setModifiedCount(img.getModifiedCount() + 1);
64. img.setLastModified(CalendarUtil.getCurrentDate()
65. .getTime());
66. imageManager.updateImage(img);
67.
68. Runnable task = new UploadThread(img);
69. threadPool.execute(task);
70. }
71.
72. } catch (Exception e) {
73. log.error("获取下载图片队列失败", e);
74. }
75.
76. }
77.
78. }
79. };
80.
81. // 用于被拒绝任务的处理程序
82. final RejectedExecutionHandler handler = new RejectedExecutionHandler() {
83. public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
84. log.error(((UploadThread) r).getImg() + " 放入队列中重新等待执行");
85. msgQueue.offer(((UploadThread) r).getImg());
86. }
87. };
88.
89. // 管理数据库访问的线程池
90. final ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
91. CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS,
92. new ArrayBlockingQueue(WORK_QUEUE_SIZE), this.handler);
93.
94. // 调度线程池
95. final ScheduledExecutorService scheduler = Executors
96. .newScheduledThreadPool(1);
97.
98. final ScheduledFuture taskHandler = scheduler.scheduleAtFixedRate(
99. accessBufferThread, 0, 5, TimeUnit.SECONDS);
100.
101. public static ThreadPoolManager newInstance() {
102. return tpm;
103. }
104.
105. private ThreadPoolManager() {
106. }
107.
108. private boolean hasMoreAcquire() {
109. return !msgQueue.isEmpty();
110. }
111.
112. private boolean hasImagesInDB() {
113. boolean result = false;
114. try {
115. BeanFactoryService beanFactory = (BeanFactoryService) BizServiceManager
116. .getInstance().getService(BeanFactoryService.SERVICE_NAME);
117. if (beanFactory == null)
118. return false;
119. ImageManager imageManager = (ImageManager) beanFactory
120. .getBean("imageManager");
121. if (imageManager == null)
122. return false;
123. int imagesCount = imageManager.getImagesCount(ImageDO.STATE_READY);
124. result = (imagesCount != 0);
125. } catch (Exception e) {
126. log.error("获取下载图片队列失败", e);
127. }
128. return result;
129. }
130.
131. public void processImg(ImageDO img) {
132. Runnable task = new UploadThread(img);
133. threadPool.execute(task);
134. }
135.
136.
137. public long getCompleteTasksCount() {
138. return this.threadPool.getCompletedTaskCount();
139. }
140.
141. public long getActiveTasksCount() {
142. return this.threadPool.getActiveCount();
143. }
144.
145. public long getAllTasksCount() {
146. return this.threadPool.getTaskCount();
147. }
148.
149. public long getQuequeCount() {
150. return this.msgQueue.size();
151. }
152.
153. public boolean getRunningStatus() {
154. return !this.threadPool.isShutdown();
155. }
156.
157. public long getScheduledQuequeSize() {
158. return ((ScheduledThreadPoolExecutor)this.scheduler).getQueue().size();
159. }
160.
161. }
162.
163.
164.
165. public class UploadThread implements Runnable {
166. private ImageDO img;
167.
168. protected Logger log = LoggerFactory.getLogger(UploadThread.class);
169.
170. public ImageDO getImg() {
171. return img;
172. }
173.
174. public void setImg(ImageDO img) {
175. this.img = img;
176. }
177.
178. public UploadThread() {
179. super();
180. }
181.
182. public UploadThread(ImageDO img) {
183. this.img = img;
184. }
185.
186. public void run() {
187. BeanFactoryService beanFactory = (BeanFactoryService) BizServiceManager
188. .getInstance().getService(BeanFactoryService.SERVICE_NAME);
189. ImageManager imageManager = (ImageManager) beanFactory
190. .getBean("imageManager");
191. if (UploadUtil.upload(img)) {
192. try {
193. log.error("下載圖片成功:"+ img);
194. imageManager.deleteImageByid(img.getId());
195. } catch (ManagerException e) {
196. log.error("删除图片记录失败:"+ img.getId(), e);
197. }
198. } else {
199. img.setState(ImageDO.STATE_FAIL);
200. try {
201. imageManager.updateImage(img);
202. } catch (ManagerException e) {
203. log.error("设置图片下载状态失败:"+ img.getId(), e);
204. }
205. }
206. }
207.
208. }
209. public class UploadUtil {
210. private static Logger logger = Logger.getLogger(UploadUtil.class);
211. private static FileStorage attachmentFileStorage;
212.
213. private static String imgServer;
214.
215. /**
216. * @param imgServer
217. * the imgServer to set
218. */
219. public void setImgServer(String imgServer) {
220. UploadUtil.imgServer = imgServer;
221. }
222.
223. public static String getUrlPrefix() {
224. return imgServer;
225. }
226.
227. public static boolean upload(ImageDO image) {
228. String url = image.getWsrc();
229. HttpMethod httpMethod = getHttpMethod(url);
230. ByteArrayDataSource ds = new ByteArrayDataSource(httpMethod
231. .getResponseBodyAsStream(), "image/jpeg");
232. ds.setName("upload.jpg");
233. boolean result = attachmentFileStorage.save(ds, image.getLsrc());
234. httpMethod.releaseConnection();
235. return result;
236. } catch (Exception e) {
237. logger.error("upload image fail:" + url, e);
238. }
239. return false;
240. }
241.
242. private static HttpMethod getHttpMethod(String url) throws IOException {
243. HttpMethod httpMethod = new GetMethod(url);
244. httpMethod.setRequestHeader("Cache-Control", "no-cache");
245. httpMethod.setRequestHeader("Accept-Language", "zh-cn");
246. HttpClient clientTemp = new HttpClient(); // HttpClient创建
247. HttpClientParams clientParams = clientTemp.getParams();
248. clientParams.setParameter("http.socket.timeout", 5000); // 5秒socket等待数据
249. clientParams.setParameter("http.connection.timeout", 5000); // 5秒http
250. // connection建立超时
251. clientParams.setParameter("http.connection-manager.timeout", 5000L); // 5秒从http
252. // yahoo相册的图片需要设置Referer头
253. if (url.toLowerCase().indexOf("yahoo") != -1) {
254. httpMethod.addRequestHeader("Referer", "[url=http://forum.taobao.com/]http://forum.taobao.com/[/url]");
255. }
256. // connection
257. // manager获取可用的Http
258. // connection超时
259. clientParams.setParameter("http.method.retry-handler",
260. new DefaultHttpMethodRetryHandler()); // 如果Http出错,三次重试
261. clientTemp.executeMethod(httpMethod);
262. return httpMethod;
263. }
264.
265. public void setAttachmentFileStorage(FileStorage attachmentFileStorage) {
266. UploadUtil.attachmentFileStorage = attachmentFileStorage;
267. }
268.
269. public static void main(String[] args) throws Exception {
270. HttpMethod httpMethod = getHttpMethod("[url=http://cn.photos.yahoo.com/users/47df51c0z8a48b60a/255c/__sr_/dbce.jpg?wa86dTAyD7Rq05sklm3fMQ--&F18]http://cn.photos.yahoo.com/users/47df51c0z8a48b60a/255c/__sr_/dbce.jpg?wa86dTAyD7Rq05sklm3fMQ--&F18[/url]");
271. InputStream inputStream = httpMethod.getResponseBodyAsStream();
272. FileOutputStream os = new FileOutputStream("c:/test.jpg");
273.
274. IOUtils.copy(inputStream, os);
275. os.close();
276.
277. httpMethod.releaseConnection();
278. }
279. }
280.
281.
282. public class HtmlParseUtil {
283. protected static Logger log = LoggerFactory.getLogger(HtmlParseUtil.class);
284.
285. public static String processImg(String imageURL) {
286. if (imageURL.toLowerCase().indexOf("taobao.com") == -1) {
287. BeanFactoryService beanFactory = (BeanFactoryService) BizServiceManager
288. .getInstance().getService(BeanFactoryService.SERVICE_NAME);
289. ImageManager imageManager = (ImageManager) beanFactory
290. .getBean("imageManager");
291. FileStorage fileStorage = (FileStorage) beanFactory
292. .getBean("attachmentFileStorage");
293.
294. // 产生本地扯的图片文件名
295. String localFileName = FileNameGenerater
296. .getLocalFileName("upload.jpg");
297.
298. ImageDO image = new ImageDO();
299. image.setWsrc(imageURL);
300. image.setState(ImageDO.STATE_READY);
301. image.setLsrc(localFileName);
302. image.setLastModified(CalendarUtil.getCurrentDate().getTime());
303.
304. try {
305. imageManager.insertImage(image);
306.
307. log.error("新增图片下载:" + image);
308. ThreadPoolManager tpm = ThreadPoolManager.newInstance();
309. tpm.processImg(image);
310.
311. return UploadUtil.getUrlPrefix() + fileStorage.getNamespace()
312. + "/" + localFileName;
313. } catch (ManagerException e) {
314. log.error("新增图片下载失败:" + imageURL, e);
315. }
316. }
317. return imageURL;
318. }
319.
320. }

Posted on July 1, 2009 4:08 PM | | Comments (0) | TrackBacks (0)

Eclipse 3.5 的新特性一览表:

新特性包括:

平台及UI

* Solaris x86已经加入支持行列
* Install New Software向导中的“Work with:”下拉框现在支持自动补全
* 增加了一个新的介绍主题,叫做“Slate”
* 打开的编辑器及多编辑器页面间的切换更加容易(快捷键:Ctrl+PageDown/Ctrl+PageUp,Alt+PageDown/Alt+PageUp)
* 为了快速关闭,现在可以安全地跳过清楚历史这一步骤
* 至于编辑器的常规提示框和对话框,或当前工作台窗口、表单现在可以在Mac Cocoa上使用
* 应用程序在打印过程中或打开打印对话框时,可以选择portrait或landscape模式
* Eclipse富客户端平台现在包含了一个OSGi声明式服务(Declarative Services——DS)的实现
* 你现在可以针对给定选项“钉住”属性视图
* 一个新偏好页,可以管理用于选择工作区的启动提示框
* About对话框现在提供一种机制,让plug-in可以给平台about对话框提供安装页面
* Install New Software向导现在无需等待连接任何更新服务器就可以立即打开
* 双击垂直折叠线(vertical folding line)可以折起折叠区域
* 比较编辑器有几处增强
* 你现在可以在Debug视图中快速切换挂起线程
* 支持Cocoa和Cocoa上的OpenGL
* 增加对FileTransfer类的支持,使得可以在Explorer和Nautilus文件管理器之间进行copy/paste操作
* 对项目浏览器作出几项改进
* 文本编辑器现在支持块选择模式(也就是按列选择或矩形块选择)
* 你现在可以直接在Synchronize视图中应用一个补丁
* 在Eclipse中比较Word文档变化,现在使用该Word比较功能支持把变化显示为修订

Equinox

* 增强Equinox DebugOptions API,以支持选项设置的动态变化
* 增加一个新的debug跟踪API——org.eclipse.osgi.service.debug.DebugTrace,以增强并简化编写debug跟踪信息
* OSGi R4.2核心规范给核心框架增加了一些小API
* 新的Equinox并发API

Plug-in开发环境

* 有一个新的Target Platform State(目标平台状态)视图
* 你现在可以创建并共享一个由软件站点的软件组成的目标定义
* 新的Category Definition编辑器可以在输出时用于给特性归类
* 你现在可以查看API相对于API基线的变化
* 通过在菜单introspection mode里调用plug-in Spy来查看关于菜单的信息
* 增强OSGi Declarative Services (DS),以支持最新版的DS规范
* 你现在可以从OSGi启动配置中初始化产品定义
* 有一个新的目标平台偏好页面
* PPlug-in export现在支持创建source bundles
* Declarative Services现在支持最新版的OSGi declarative services规范(1.1)更新
* PDE中的JAR signing支持扩展包含了对keypass的支持
* 增强目标编辑器,以支持目标定义中的新特性
* API工具现在可以分析系统类库的使用情况及代码访问运行时不存在的成员时所产生的问题
* 你现可以在非UI线程中启动Junit Plug-in测试
* Eclipse应用程序启动配置现在支持启动级别(start level)及自动启动设置
* Plug-in Registry视图现在支持浏览OSGi服务
* 给PDE/Build增加了一个新的扩展,可以使用户从p2库中获取制品
* API工具现在支持在接口上的两个约束:@noimplement 和 @noextend。这就使得在不想直接实现一个接口的时候可以扩展它
* 即使你已经增大了plug-in的主版本号,仍会被提示破坏API的改变
* PDE增强了bundle及特性(feature)输出,以把输出的bundles/feature安装到当前正在运行的工作台
* 输出特性、plug-in及产品时可以选择binary cycles
* PDE增加了declarative services工具,以帮助作者提供组件定义

Java开发工具

* NLS string hover现在有一个Open in Properties File动作
* 在Caller模式下,调用层级(Call Hierarchy)现在有一个在上下文菜单中有一个Expand With Constructors动作
* 当你在编辑器中输入的时候,Java比较编辑器会更新其结构
* 有一个新的toString()产生器
* 为可覆盖方法增加了一个Open Implementation链接,可以直接打开其实现
* 编辑器与执行环境一致
* Debug视图现在提供了breadcrumb(面包屑),显示了当前活动的debug上下文
* 可运行的JAR文件输出向导还可以把所需的类库打包进一个要输出的可运行JAR文件,或打包进与紧挨着该JAR的一个目录中
* 当在写一个分配表达式(allocation expression)时发生补全操作,内容助手现在可以提示一个类的可用构造方法
* 如果检测到无用代码,编译器现在可以发出警告
* 类库、变量或容器入口的路径现在可以是与项目相关的任何位置
* 在Jovadoc hover的头部及Javadoc视图中,现在都提供了引用其他类型和成员的链接
* 随该Eclipse发行的JUnit4版本更新为4.5
* Javadoc视图及hovers现在都支持{@inheritDoc}标签并给覆盖方法增加链接
* 同一值的比较现在由编译器检测,默认情况下会发出警告

下载地址:http://www.eclipse.org/downloads/

Posted on June 25, 2009 12:35 PM | | Comments (0) | TrackBacks (0)

Sun近日放出了Java SE Runtime Environment 6的第14个升级版,亦即Java SRE 6u14,内部版本号为1.6.0_14-b08。

对Windows用户来说,新版Java首先正式加入了对Vista SP2和Server 2008 SP2的支持,并初步支持Windows 7系统和IE8浏览器。

其他主要新特性:

- 在Linux、Solaris系统上支持Service Tag

- 支持JAR文件黑名单

- 支持新版虚拟机Java HotSpot 14.0

- 改进TreeMap性能 (java.util.TreeMap)

- 集成JAX WS 2.1.6、JAXB 2.1.10

- 集成JavaDB 10.4.2.1

- Java VisualVM大幅度升级

- 完善支持JDK静默安装,不会再出现不安装公有JRE的情况

- Java Web Start问题修正

- 解决其他大量bug

详细更新日志可以参考这里。

JRE 6 Upate 14官方下载:
https://cds.sun.com/is-bin/INTERSHOP.enfinity/WFS/CDS-CDS_Developer-Site/en_US/-/USD/ViewProductDetail-Start?ProductRef=jre-6u14-oth-JPR@CDS-CDS_Developer

JDK 6 Update 14官方下载:
https://cds.sun.com/is-bin/INTERSHOP.enfinity/WFS/CDS-CDS_Developer-Site/en_US/-/USD/ViewProductDetail-Start?ProductRef=jdk-6u14-oth-JPR@CDS-CDS_Developer (驱动之家)

Posted on June 2, 2009 11:58 AM | | Comments (0) | TrackBacks (0)

本文列述了13个Java程序员应当学习Flex和BlazeDS的理由,讨论了为什么Flex结合BlazeDS是开发RIA的最佳组合之一。无论是高度交互的网站还是以Java为后端的企业应用,这项组合都是最佳选择之一。更重要的是,这项组合能同时为开发员和企业带来高回报(ROI)。

在阐述Java程序员应当学习BlazeDS的13条理由时,我以一个假想的苏打分派系统来展示如何让已有的Java程序转变为RIA应用。通过这个例子,我同时还会讲解到BlazeDS在已有Java应用或新建Java应用中的多种不同用法。
理由一:开源

Flex软件开发工具箱(SDK)的核心是个开源框架,专门用来开发、维护那些在不同浏览器、不同操作系统下界面都相同的RIA应用。Flex发布采用的是Mozilla公共许可证(Mozilla Public License)。编译后的Flex应用在Adobe Flash平台下运行。

BlazeDS是连接Flex和Java的索桥,是项针对远程调用和消息传递的开源技术。在Java应用服务器上,它以servlet的形式存在,因此可以在任何标准Java网络应用中运用它。BlazeDS以LGPL(Lesser GNU Public License)公共许可证书发布。在发布BlazeDS的同时,Adobe还公布了AMF(ActionScript Message Format)规格说明,BlazeDS、Java和Flex客户端间以这种简洁的二进制格式实现通信。
理由二:完善的社区支持

Flex社区非常活跃,社区贡献了大量项目。Flex.org,这个配以社区新闻的Adobe站点几乎每天都有新的社区贡献;Yahoo!上的Flex用户组的成员也已经超过了11000。

再比如Google Code上的Flexlib项目,已经提交了大量的开源UI组件。Swiz和Mate项目贡献了优化事件处理的框架;还有Gorilla Logic贡献了自动化UI测试的Flex Monkeym项目。
理由三:带来广阔的就业前景

据Adobe的Flex“传道士”——James Ward看来,Flex高级开发员的市场需求非常大,学习Flex能让你拥有极具市场竞争力的开发技能。
理由四:更高的业务效益回报

总体上,开发企业web应用不是个轻松的活,这基本上是众所周知的事实。Flex和BlazeDS提供的不仅仅是功能强大的开发工具,而且开发技术本身相对也非常简单。开发效率可以得到大幅度的提升,产品因此可以很快推向市场。Flex和Flash带来的用户体验也相对更有魅力,对增加流量、提高用户转化率(conversion rate)很有帮助。

很经典的一个例子是Borders连锁书店。他们最近发布了带有“魔法书架”的新网站,这个网站采用Flash接口来模拟书籍借阅的过程。 Borders 发现这一模拟借阅非常明显地提到了用户转换率:“借助这个Flash驱动的接口,用户可以浏览书籍、DVD和CD的封面,用户转换率比其他没有此项功能的网站高出62%”
理由五:Flex是第一个专门为创建UI而设计的语言

大部分语言都不是在第一时间设计其对UI的支持。Java中Swing包的实现刚好是个很好的证明。也就是这个原因,很多像捆绑数据这样的简单动作在Swing当中的实现就非常痛苦。用 Swing最大的问题在于,要想提高开发效率就必须要对其API了如指掌。

Flex刚好相反,它是专门为创建web UI而设计的。正如Bruce Eckel所说,Flex是第一个针对UI开发的领域特定语言(DSL)。用Flex构建UI比其它诸如JSP、JSF、Swing等技术简便得多。语言本身糅合了数据绑定、事件处理、控件布局以及其它一些UI常用开发技巧,就算对语言没有深刻的理解也不会影响开发效率。
理由六:编程风格近似于Java

你可以继续使用现有的Java开发工具来开发Flex应用。当然也可以采用SDK中携带的免费命令行工具,Adobe Flex Builder(一个Eclipse插件),或最近的IntelliJ IDEA 8。

Flex提供的是一个有状态环境,在这个环境中,数据从客户端加载。这种编程模式更像是开发桌面客户端而非HTML编程,这种风格对于用过Java Swing编程的开发员来说应该是相当熟悉。

Flex是MXML(类似XML的UI标记语言)和Adobe ActionScript(面向对象的解析语言)的结合体。鉴于这种结合方式,Flex编程与Java非常相似,因为两者用的都是熟知的面向对象的概念。

最理想的开发环境是把Flex应用创建在web部署文件夹下。这样一来,每次更新应用之后都不需要重新部署,只要在浏览器下刷新一下就可以了。用Flex和BlazeDS开发后,开发效率绝对比之前有很大的提升。
理由七:BlazeDS可以在任何Java应用服务器上运行

BlazeDS目前已发布了多个版本,其中的turnkey版本还包含了为BlazeDS配置的Apache Tomcat。本文中,我用的是二进制发布版本,其中含有一个WAR用来展示如何把应用部署到各种应用服务器上去。不用这个WAR的话,你也可以从中提取 JAR文件放到自己的项目中去。关于安装BlazeDS的各种选项内容,可以参见BlazeDS的wiki

这里举一个简单的例子,比方说要在已有的一个简单的苏打调配系统中应用BlazeDS。你只要把JAR文件放到项目文件夹下,然后就可以在应用里直接用BlazeDS,可以部署到能够部署应用的任何地方。

在项目中添加BlazeDS,只需要完成下面两个步骤:

1. 解压缩BlazeDS WAR文件的内容:jar xvf blazeds.war。
2. 把JAR文件都拷贝到项目的lib文件夹下:cp -R WEB-INF/lib /sodaSample。

理由八:可以在已有Java应用中运用

比方说这个简单的苏打调配系统,假设你想要扩展这个已开发好的服务,让其它Flex应用可以远程调用。在现成的应用中配置BlazeDS的基本步骤有:

1. 修改WEB-INF/flex文件夹下的BlazeDS配置文件
2. 在该应用对应的web.xml文件里定义MessageBrokerServlet和session监听器

配置好BlazeDS之后,再把苏打调配服务添加到BlazeDS远程配置文件里,Flex客户就能远程调用了。这个过程通过在配置文件里定义一个目的地(destination)、一个或多个信道(channel)来传输数据。基本的AMF信道定义在services.xml文件里。下面这段配置在 remoting-config.xml里定义了目的地(destination):



com.gorillalogic.sodaSample.SodaService

通过在远程调用配置文件里定义端点(endpoint),Flex客户端就可以调用任何一个基本的Java服务。

要是想把Java数据模型也传送到Flex客户端的话,只要在ActionScript类中定义好两者间的映射:

[Bindable]
[RemoteClass(alias="com.gorillalogic.sodaSample.SodaModel")]

这段代码告诉Flex,在远程调用的服务返回SodaModel的时候,把它映射到Flex的SodaModel。本例中的Flex客户端显示的就是如何调用这个Java服务。调用返回一个已经填写好预定信息的SodaModel:

public function callSodaService():void {
var sodaType:String = type.text;
var sodaCount:int = parseInt(cnt.text);
var flag:Boolean = preOpen.selected;
remoteObject.getSoda(sodaType, sodaCount, flag);
}

private function resultHandler(event:ResultEvent):void {
var sodaModel:SodaModel = event.result as SodaModel;
}

Flex返回的结果是通用的result变量,可以直接映射到你的SodaModel。这里我就不深入讨论怎么实现映射了,但其中值得提到的是要在编译配置里声明services-config.xml路径,像这样:

-locale en_US -services=/nsource/sodaSample/web/WEB-INF/flex/services-config.xml -context-root /

如果不添加这个路径的话,你的Flex客户端就没发找到Java服务。同样的方式,你还能把一个对象从客户端传递回服务器端。比如,你可以把一个空的soda model发回服务器(审校注:原文这里写的是客户端,根据上下文判断这里应该是服务器端)。
理由九:可以通过Java来扩展和修改BlazeDS

假如你想添加特殊的日志来记录苏打调配服务被调用的情况,那么你可以扩展标准的Java适配器来添加日志功能。

首先,添加一个继承了JavaAdapter的Java类:

import flex.messaging.services.remoting.adapters.JavaAdapter.
public class TimingJavaAdapter extends JavaAdapter {

其次,重载invoke()方法:

public Object invoke(Message message) {
RemotingMessage remotingMessage = (RemotingMessage) message;
String operation = remotingMessage.getOperation();
String destination = remotingMessage.getDestination();

Logger.info("calling " + operation + " on destination " + destination);
Object data = super.invoke(message);
return data;
}

这个方法中,你可以看到调用之后的操作和调用的目的地(destination)。这种方法也能用来处理其它一些问题,比如记录向服务器发送调用需要多长时间。
理由十:HTML和JSP也能调用BlazeDS

从HTML和JSP也能调用BlazeDS,这种调用有几种不同的实现方式,比如通过Browser Manager或fflashVarsf来实现。Flex应用能够读取由HTML页面设置的fflashVarsf。

比方说你想要通过HTML页面来发送你的用户名和准备预定的苏打类型,你可以在HTML页面这样设置flashVars:





然后,在Flex应用中,你可以通过读取应用参数来获取这些变量:

var username:String;
if (Application.application.parameters.hasOwnProperty("username")) {
username = Application.application.parameters.username;
}

理由十一:Flex和BlazeDS的数据传输性能远胜于其它Ajax解决方案

目前使用的远程过程调用(RPC)都默认选择AMF二进制协议。AMF是个开放的标准,而且相当快。James Ward曾举例比较过多种远程调用解决方案。尽管其它Ajax技术——比如Dojo——已经能够快速处理几百行的数据,但是用Flex和BlazeDS的话可以轻松搞定成千上万行。(请参考James Ward's census,可以了解下各种不同的RIA数据加载技术的测评。)
理由十二:Java客户端能够直接调用BlazeDS

最新发布的BlazeDS当中含有一个Java的AMF类,通过这个类,你可以在Java客户端直接调用BlazeDS服务器。对于单元测试和加载测试来说,BlazeDS的这种调用方式非常实用。
理由十三:Spring下也能用

Adobe和Spring互相联手,尝试将双方项目集成起来。他们发布的第一个Spring–BlazeDS集成版本就向大家展示了他们的良苦用心。Spring Bean能够以远程服务的方式被调用,因此可以清除很多重复的配置文件。更多这方面的相关信息,可以参考该项目的主页
结论

开源的BlazeDS创建在Java基础上,无论是对新的还是已有的Java服务器项目来说都是个很好的选择。Flex、BlazeDS技术能够提供高性能的远程通信,支持Flex和Java间的对象映射,因此是RIA开发的理想选择。Flex和BlazeDS的开发新手,如果曾经是Java开发员的话,会发现整个开发过程效率非常高,而且很容易掌握。

Flex加BlazeDS还是开发大型Java企业应用的理想选择。我们组开发的上个项目中,应用涉及到50多个不同的界面,而且服务器和客户端之间需要规律性地互传几千行的代码。这类应用几乎没法通过传统的Ajax技术来实现。但是在引入了Flex和BlazeDS之后,我们在年内就发布了第一个版本。看,这就是这对动态组合为你的应用开发项目带来的过人之处。(百度空间)

Posted on June 2, 2009 11:43 AM | | Comments (0) | TrackBacks (0)

FlamingoBuilder*最新版发布了,在这里可以下载!

FlamingoBuilder是SwingBuilder家族的一员,它使得用户可以充分利用 Flamingo 组件套装。此次的新发布版添加了对最复杂(而且最难配置)的Flamingo*组件:Ribbon的支持。

现在,以下的组件都在你的掌控之中了:

ribbonFrame
ribbon
ribbonTask
ribbonContextualTaskGroup
ribbonBand
ribbonFlowBand
ribbonComponent
ribbonApplicationMenu
ribbonApplicationMenuEntryFooter

译者注:
*FlamingoBuilder:针对开源Swing组件套装Flamingo的基于Groovy语言的 Builder。

*Flamingo:Flamingo是一个Swing组件套装,设计目的是提供小巧但功能强大的UI组件,这些组件具有与Vista Explorer和Office 2007相似外观和功能因此可以取其而代之。(CSDN)

Posted on May 21, 2009 10:43 AM | | Comments (0) | TrackBacks (0)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
相关内容
最新评论
[评论] Candy : 呵呵,我的博客也升级了!
[评论] chongtu : 有这样的事?嗳!网络分享这个词的悲哀啊。。。
[评论] Lisa : 互联网现在越来越深入到我们的工作,甚至生活中。
[评论] Lisa Chen : 说的很全面,谢谢楼主的分享~
[评论] Lisa : 收录的网站好全,谢谢楼主的辛苦收集~
[评论] Texas Holdem : hey,looks like we’re on the same path. good stuff!
[评论] 向日葵 : 很好的信息,收录的网站也挺全的。非常感谢楼主拿出来分享。
[评论] : 电视导购的确很让人痛苦 网购还是专业的导购站比较好的!~ <a href="http://www.t
[评论] lindou : 试试用国产的speedphp框架吧,那速度挺快的,而且教程比较多。
[评论] allsyringefilters : 哎,这是雅虎的悲哀啊..当年那么高的价格收购,到如今...哎