|
Jetty example source code file (java5.patch)
The Jetty java5.patch source code
Index: modules/jetty/src/test/java/org/mortbay/jetty/HttpServerTestBase.java
===================================================================
--- modules/jetty/src/test/java/org/mortbay/jetty/HttpServerTestBase.java (revision 2256)
+++ modules/jetty/src/test/java/org/mortbay/jetty/HttpServerTestBase.java (working copy)
@@ -236,7 +236,7 @@
{
int[] points=new int[pointCount];
- StringBuffer message=new StringBuffer();
+ StringBuilder message=new StringBuilder();
message.append("iteration #"+(i+1));
@@ -281,7 +281,7 @@
for (int i=0; i<bytes.length; i+=3)
{
int[] points=new int[] { i };
- StringBuffer message=new StringBuffer();
+ StringBuilder message=new StringBuilder();
message.append("iteration #"+(i+1));
@@ -333,7 +333,7 @@
{
Socket client=new Socket(HOST,port);
OutputStream os=client.getOutputStream();
- StringBuffer message=new StringBuffer();
+ StringBuilder message=new StringBuilder();
message.append("iteration #"+(i+1));
writeFragments(bytes,badPoints[i],message,os);
@@ -691,7 +691,7 @@
{
br=new BufferedReader(new InputStreamReader(client.getInputStream()));
- StringBuffer sb=new StringBuffer();
+ StringBuilder sb=new StringBuilder();
String line;
while ((line=br.readLine())!=null)
@@ -738,7 +738,7 @@
return server;
}
- private void writeFragments(byte[] bytes, int[] points, StringBuffer message, OutputStream os) throws IOException, InterruptedException
+ private void writeFragments(byte[] bytes, int[] points, StringBuilder message, OutputStream os) throws IOException, InterruptedException
{
int last=0;
Index: modules/jetty/src/main/java/org/mortbay/jetty/NCSARequestLog.java
===================================================================
--- modules/jetty/src/main/java/org/mortbay/jetty/NCSARequestLog.java (revision 2256)
+++ modules/jetty/src/main/java/org/mortbay/jetty/NCSARequestLog.java (working copy)
@@ -226,76 +226,74 @@
if (_fileOut == null)
return;
- StringBuffer buf = new StringBuffer(160);
+ StringBuilder buf = new StringBuilder(160);
String log =null;
- synchronized(buf) // for efficiency until we can use StringBuilder
+ if (_logServer)
{
- if (_logServer)
- {
- buf.append(request.getServerName());
- buf.append(' ');
- }
+ buf.append(request.getServerName());
+ buf.append(' ');
+ }
- String addr = null;
- if (_preferProxiedForAddress)
- {
- addr = request.getHeader(HttpHeaders.X_FORWARDED_FOR);
- }
+ String addr = null;
+ if (_preferProxiedForAddress)
+ {
+ addr = request.getHeader(HttpHeaders.X_FORWARDED_FOR);
+ }
- if (addr == null)
- addr = request.getRemoteAddr();
+ if (addr == null)
+ addr = request.getRemoteAddr();
- buf.append(addr);
- buf.append(" - ");
- String user = request.getRemoteUser();
- buf.append((user == null)? " - " : user);
- buf.append(" [");
- if (_logDateCache!=null)
- buf.append(_logDateCache.format(request.getTimeStamp()));
- else
- buf.append(request.getTimeStampBuffer().toString());
-
- buf.append("] \"");
- buf.append(request.getMethod());
- buf.append(' ');
- buf.append(request.getUri());
- buf.append(' ');
- buf.append(request.getProtocol());
- buf.append("\" ");
- int status = response.getStatus();
- if (status<=0)
- status=404;
- buf.append((char)('0'+((status/100)%10)));
- buf.append((char)('0'+((status/10)%10)));
- buf.append((char)('0'+(status%10)));
+ buf.append(addr);
+ buf.append(" - ");
+ String user = request.getRemoteUser();
+ buf.append((user == null)? " - " : user);
+ buf.append(" [");
+ if (_logDateCache!=null)
+ buf.append(_logDateCache.format(request.getTimeStamp()));
+ else
+ buf.append(request.getTimeStampBuffer().toString());
+ buf.append("] \"");
+ buf.append(request.getMethod());
+ buf.append(' ');
+ buf.append(request.getUri());
+ buf.append(' ');
+ buf.append(request.getProtocol());
+ buf.append("\" ");
+ int status = response.getStatus();
+ if (status<=0)
+ status=404;
+ buf.append((char)('0'+((status/100)%10)));
+ buf.append((char)('0'+((status/10)%10)));
+ buf.append((char)('0'+(status%10)));
- long responseLength=response.getContentCount();
- if (responseLength >=0)
+
+ long responseLength=response.getContentCount();
+ if (responseLength >=0)
+ {
+ buf.append(' ');
+ if (responseLength > 99999)
+ buf.append(Long.toString(responseLength));
+ else
{
- buf.append(' ');
- if (responseLength > 99999)
- buf.append(Long.toString(responseLength));
- else
- {
- if (responseLength > 9999)
- buf.append((char)('0' + ((responseLength / 10000)%10)));
- if (responseLength > 999)
- buf.append((char)('0' + ((responseLength /1000)%10)));
- if (responseLength > 99)
- buf.append((char)('0' + ((responseLength / 100)%10)));
- if (responseLength > 9)
- buf.append((char)('0' + ((responseLength / 10)%10)));
- buf.append((char)('0' + (responseLength)%10));
- }
- buf.append(' ');
+ if (responseLength > 9999)
+ buf.append((char)('0' + ((responseLength / 10000)%10)));
+ if (responseLength > 999)
+ buf.append((char)('0' + ((responseLength /1000)%10)));
+ if (responseLength > 99)
+ buf.append((char)('0' + ((responseLength / 100)%10)));
+ if (responseLength > 9)
+ buf.append((char)('0' + ((responseLength / 10)%10)));
+ buf.append((char)('0' + (responseLength)%10));
}
- else
- buf.append(" - ");
-
- log = buf.toString();
+ buf.append(' ');
}
-
+ else
+ buf.append(" - ");
+
+ log = buf.toString();
+
+
synchronized(_writer)
{
_writer.write(log);
Index: modules/jetty/src/main/java/org/mortbay/jetty/InclusiveByteRange.java
===================================================================
--- modules/jetty/src/main/java/org/mortbay/jetty/InclusiveByteRange.java (revision 2256)
+++ modules/jetty/src/main/java/org/mortbay/jetty/InclusiveByteRange.java (working copy)
@@ -175,7 +175,7 @@
/* ------------------------------------------------------------ */
public String toHeaderRangeString(long size)
{
- StringBuffer sb = new StringBuffer(40);
+ StringBuilder sb = new StringBuilder(40);
sb.append("bytes ");
sb.append(getFirst(size));
sb.append('-');
@@ -188,7 +188,7 @@
/* ------------------------------------------------------------ */
public static String to416HeaderRangeString(long size)
{
- StringBuffer sb = new StringBuffer(40);
+ StringBuilder sb = new StringBuilder(40);
sb.append("bytes */");
sb.append(size);
return sb.toString();
@@ -198,7 +198,7 @@
/* ------------------------------------------------------------ */
public String toString()
{
- StringBuffer sb = new StringBuffer(60);
+ StringBuilder sb = new StringBuilder(60);
sb.append(Long.toString(first));
sb.append(":");
sb.append(Long.toString(last));
Index: modules/jetty/src/main/java/org/mortbay/jetty/servlet/HashSessionIdManager.java
===================================================================
--- modules/jetty/src/main/java/org/mortbay/jetty/servlet/HashSessionIdManager.java (revision 2256)
+++ modules/jetty/src/main/java/org/mortbay/jetty/servlet/HashSessionIdManager.java (working copy)
@@ -25,7 +25,7 @@
import org.mortbay.jetty.SessionIdManager;
import org.mortbay.jetty.servlet.AbstractSessionManager.Session;
import org.mortbay.log.Log;
-import org.mortbay.util.MultiMap;
+import org.mortbay.util.ConcurrentMultiMap;
/* ------------------------------------------------------------ */
/**
@@ -37,7 +37,7 @@
protected final static String SESSION_ID_RANDOM_ALGORITHM = "SHA1PRNG";
protected final static String SESSION_ID_RANDOM_ALGORITHM_ALT = "IBMSecureRandom";
- MultiMap _sessions;
+ ConcurrentMultiMap _sessions;
protected Random _random;
private boolean _weakRandom;
private String _workerName;
@@ -133,7 +133,7 @@
}
}
_random.setSeed(_random.nextLong()^System.currentTimeMillis()^hashCode()^Runtime.getRuntime().freeMemory());
- _sessions=new MultiMap();
+ _sessions=new ConcurrentMultiMap();
}
/* ------------------------------------------------------------ */
@@ -159,10 +159,7 @@
*/
public void addSession(HttpSession session)
{
- synchronized (this)
- {
- _sessions.add(getClusterId(session.getId()),session);
- }
+ _sessions.add(getClusterId(session.getId()),session);
}
/* ------------------------------------------------------------ */
@@ -171,10 +168,7 @@
*/
public void removeSession(HttpSession session)
{
- synchronized (this)
- {
- _sessions.removeValue(getClusterId(session.getId()),session);
- }
+ _sessions.removeValue(getClusterId(session.getId()),session);
}
/* ------------------------------------------------------------ */
@@ -183,19 +177,16 @@
*/
public void invalidateAll(String id)
{
- synchronized (this)
- {
- // Do not use interators as this method tends to be called recursively
- // by the invalidate calls.
- while (_sessions.containsKey(id))
- {
- Session session=(Session)_sessions.getValue(id,0);
- if (session.isValid())
- session.invalidate();
- else
- _sessions.removeValue(id,session);
- }
- }
+ // Do not use interators as this method tends to be called recursively
+ // by the invalidate calls.
+ while (_sessions.containsKey(id))
+ {
+ Session session=(Session)_sessions.getValue(id,0);
+ if (session.isValid())
+ session.invalidate();
+ else
+ _sessions.removeValue(id,session);
+ }
}
/* ------------------------------------------------------------ */
@@ -259,4 +250,4 @@
_weakRandom=false;
}
-}
\ No newline at end of file
+}
Index: modules/jetty/src/main/java/org/mortbay/jetty/servlet/ServletHandler.java
===================================================================
--- modules/jetty/src/main/java/org/mortbay/jetty/servlet/ServletHandler.java (revision 2256)
+++ modules/jetty/src/main/java/org/mortbay/jetty/servlet/ServletHandler.java (working copy)
@@ -21,6 +21,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
@@ -94,7 +95,7 @@
private transient Map _servletNameMap=new HashMap();
private transient PathMap _servletPathMap;
- protected transient HashMap _chainCache[];
+ protected transient ConcurrentHashMap _chainCache[];
/* ------------------------------------------------------------ */
@@ -139,7 +140,7 @@
updateMappings();
if(_filterChainsCached)
- _chainCache= new HashMap[]{null,new HashMap(),new HashMap(),null,new HashMap(),null,null,null,new HashMap()};
+ _chainCache= new ConcurrentHashMap[]{null,new ConcurrentHashMap(),new ConcurrentHashMap(),null,new ConcurrentHashMap(),null,null,null,new ConcurrentHashMap()};
super.doStart();
@@ -468,17 +469,13 @@
if (_filterChainsCached && _chainCache!=null)
{
- synchronized(this)
- {
- if(_chainCache[requestType].containsKey(key))
- return (FilterChain)_chainCache[requestType].get(key);
- }
+ FilterChain chain = (FilterChain)_chainCache[requestType].get(key);
+ if (chain!=null)
+ return chain;
}
-
// Build list of filters
Object filters= null;
-
// Path filters
if (pathInContext!=null && _filterPathMappings!=null)
@@ -523,12 +520,9 @@
{
if (LazyList.size(filters) > 0)
chain= new CachedChain(filters, servletHolder);
- synchronized(this)
- {
- if (_maxFilterChainsCacheSize>0 && _chainCache[requestType].size()>_maxFilterChainsCacheSize)
- _chainCache[requestType].clear();
- _chainCache[requestType].put(key,chain);
- }
+ if (_maxFilterChainsCacheSize>0 && _chainCache[requestType].size()>_maxFilterChainsCacheSize)
+ _chainCache[requestType].clear();
+ _chainCache[requestType].put(key,chain);
}
else if (LazyList.size(filters) > 0)
chain = new Chain(filters, servletHolder);
@@ -1150,7 +1144,7 @@
/* ------------------------------------------------------------ */
public String toString()
{
- StringBuffer b = new StringBuffer();
+ StringBuilder b = new StringBuilder();
for (int i=0; i<LazyList.size(_chain);i++)
{
b.append(LazyList.get(_chain, i).toString());
Index: modules/jetty/src/main/java/org/mortbay/jetty/servlet/HashSessionManager.java
===================================================================
--- modules/jetty/src/main/java/org/mortbay/jetty/servlet/HashSessionManager.java (revision 2256)
+++ modules/jetty/src/main/java/org/mortbay/jetty/servlet/HashSessionManager.java (working copy)
@@ -30,6 +30,8 @@
import java.util.Timer;
import java.util.TimerTask;
+import java.util.concurrent.ConcurrentHashMap;
+
import javax.servlet.http.HttpServletRequest;
import org.mortbay.log.Log;
@@ -43,6 +45,7 @@
*/
public class HashSessionManager extends AbstractSessionManager
{
+ private static int __id;
private Timer _timer;
private TimerTask _task;
private int _scavengePeriodMs=30000;
@@ -63,10 +66,10 @@
*/
public void doStart() throws Exception
{
- _sessions=new HashMap();
+ _sessions=new ConcurrentHashMap(); // TODO: use syncronizedMap for JDK 1.4
super.doStart();
- _timer=new Timer(true);
+ _timer=new Timer("HashSessionScavenger-"+__id++, true);
setScavengePeriod(getScavengePeriod());
Index: modules/jetty/src/main/java/org/mortbay/jetty/servlet/DefaultServlet.java
===================================================================
--- modules/jetty/src/main/java/org/mortbay/jetty/servlet/DefaultServlet.java (revision 2256)
+++ modules/jetty/src/main/java/org/mortbay/jetty/servlet/DefaultServlet.java (working copy)
@@ -421,19 +421,22 @@
if (!endsWithSlash || (pathInContext.length()==1 && request.getAttribute("org.mortbay.jetty.nullPathInfo")!=null))
{
StringBuffer buf=request.getRequestURL();
- int param=buf.lastIndexOf(";");
- if (param<0)
- buf.append('/');
- else
- buf.insert(param,'/');
- String q=request.getQueryString();
- if (q!=null&&q.length()!=0)
+ synchronized(buf)
{
- buf.append('?');
- buf.append(q);
+ int param=buf.lastIndexOf(";");
+ if (param<0)
+ buf.append('/');
+ else
+ buf.insert(param,'/');
+ String q=request.getQueryString();
+ if (q!=null&&q.length()!=0)
+ {
+ buf.append('?');
+ buf.append(q);
+ }
+ response.setContentLength(0);
+ response.sendRedirect(response.encodeRedirectURL(buf.toString()));
}
- response.setContentLength(0);
- response.sendRedirect(response.encodeRedirectURL(buf.toString()));
}
// else look for a welcome file
else if (null!=(welcome=getWelcomeFile(resource)))
Index: modules/jetty/src/main/java/org/mortbay/jetty/handler/ContextHandler.java
===================================================================
--- modules/jetty/src/main/java/org/mortbay/jetty/handler/ContextHandler.java (revision 2256)
+++ modules/jetty/src/main/java/org/mortbay/jetty/handler/ContextHandler.java (working copy)
@@ -347,7 +347,7 @@
return null;
URLClassLoader loader = (URLClassLoader)_classLoader;
URL[] urls =loader.getURLs();
- StringBuffer classpath=new StringBuffer();
+ StringBuilder classpath=new StringBuilder();
for (int i=0;i<urls.length;i++)
{
try
Index: modules/jetty/src/main/java/org/mortbay/jetty/Response.java
===================================================================
--- modules/jetty/src/main/java/org/mortbay/jetty/Response.java (revision 2256)
+++ modules/jetty/src/main/java/org/mortbay/jetty/Response.java (working copy)
@@ -385,7 +385,7 @@
if (!URIUtil.hasScheme(location))
{
- StringBuffer buf = _connection.getRequest().getRootURL();
+ StringBuilder buf = _connection.getRequest().getRootURL();
if (location.startsWith("/"))
buf.append(URIUtil.canonicalPath(location));
else
Index: modules/jetty/src/main/java/org/mortbay/jetty/HttpGenerator.java
===================================================================
--- modules/jetty/src/main/java/org/mortbay/jetty/HttpGenerator.java (revision 2256)
+++ modules/jetty/src/main/java/org/mortbay/jetty/HttpGenerator.java (working copy)
@@ -368,7 +368,7 @@
HttpFields.Field transfer_encoding = null;
boolean keep_alive = false;
boolean close=false;
- StringBuffer connection = null;
+ StringBuilder connection = null;
if (fields != null)
{
@@ -439,7 +439,7 @@
default:
if (connection==null)
- connection=new StringBuffer();
+ connection=new StringBuilder();
else
connection.append(',');
connection.append(values[i]);
@@ -448,7 +448,7 @@
else
{
if (connection==null)
- connection=new StringBuffer();
+ connection=new StringBuilder();
else
connection.append(',');
connection.append(values[i]);
@@ -479,7 +479,7 @@
default:
{
if (connection==null)
- connection=new StringBuffer();
+ connection=new StringBuilder();
else
connection.append(',');
connection.append(field.getValue());
Index: modules/jetty/src/main/java/org/mortbay/jetty/security/Password.java
===================================================================
--- modules/jetty/src/main/java/org/mortbay/jetty/security/Password.java (revision 2256)
+++ modules/jetty/src/main/java/org/mortbay/jetty/security/Password.java (working copy)
@@ -122,31 +122,29 @@
/* ------------------------------------------------------------ */
public static String obfuscate(String s)
{
- StringBuffer buf = new StringBuffer();
+ StringBuilder buf = new StringBuilder();
byte[] b = s.getBytes();
-
- synchronized(buf)
+
+ buf.append(__OBFUSCATE);
+ for (int i=0;i<b.length;i++)
{
- buf.append(__OBFUSCATE);
- for (int i=0;i<b.length;i++)
- {
- byte b1 = b[i];
- byte b2 = b[s.length()-(i+1)];
- int i1= 127+b1+b2;
- int i2= 127+b1-b2;
- int i0=i1*256+i2;
- String x=Integer.toString(i0,36);
+ byte b1 = b[i];
+ byte b2 = b[s.length()-(i+1)];
+ int i1= 127+b1+b2;
+ int i2= 127+b1-b2;
+ int i0=i1*256+i2;
+ String x=Integer.toString(i0,36);
- switch(x.length())
- {
- case 1:buf.append('0');
- case 2:buf.append('0');
- case 3:buf.append('0');
- default:buf.append(x);
- }
+ switch(x.length())
+ {
+ case 1:buf.append('0');
+ case 2:buf.append('0');
+ case 3:buf.append('0');
+ default:buf.append(x);
}
- return buf.toString();
}
+ return buf.toString();
+
}
/* ------------------------------------------------------------ */
Index: modules/jetty/src/main/java/org/mortbay/jetty/security/HTAccessHandler.java
===================================================================
--- modules/jetty/src/main/java/org/mortbay/jetty/security/HTAccessHandler.java (revision 2256)
+++ modules/jetty/src/main/java/org/mortbay/jetty/security/HTAccessHandler.java (working copy)
@@ -668,7 +668,7 @@
/* ------------------------------------------------------------ */
public String toString()
{
- StringBuffer buf=new StringBuffer();
+ StringBuilder buf=new StringBuilder();
buf.append("AuthUserFile=");
buf.append(_userFile);
Index: modules/jetty/src/main/java/org/mortbay/jetty/Request.java
===================================================================
--- modules/jetty/src/main/java/org/mortbay/jetty/Request.java (revision 2256)
+++ modules/jetty/src/main/java/org/mortbay/jetty/Request.java (working copy)
@@ -1580,25 +1580,22 @@
*
* @return "scheme://host:port"
*/
- public StringBuffer getRootURL()
+ public StringBuilder getRootURL()
{
- StringBuffer url = new StringBuffer(48);
- synchronized (url)
- {
- String scheme = getScheme();
- int port = getServerPort();
+ StringBuilder url = new StringBuilder(48);
+ String scheme = getScheme();
+ int port = getServerPort();
- url.append(scheme);
- url.append("://");
- url.append(getServerName());
-
- if (port > 0 && ((scheme.equalsIgnoreCase("http") && port != 80) || (scheme.equalsIgnoreCase("https") && port != 443)))
- {
- url.append(':');
- url.append(port);
- }
- return url;
+ url.append(scheme);
+ url.append("://");
+ url.append(getServerName());
+
+ if (port > 0 && ((scheme.equalsIgnoreCase("http") && port != 80) || (scheme.equalsIgnoreCase("https") && port != 443)))
+ {
+ url.append(':');
+ url.append(port);
}
+ return url;
}
/* ------------------------------------------------------------ */
Index: modules/jetty/src/main/java/org/mortbay/xml/XmlConfiguration.java
===================================================================
--- modules/jetty/src/main/java/org/mortbay/xml/XmlConfiguration.java (revision 2256)
+++ modules/jetty/src/main/java/org/mortbay/xml/XmlConfiguration.java (working copy)
@@ -830,16 +830,13 @@
else
{
// Get the multiple items as a single string
- StringBuffer buf = new StringBuffer();
- synchronized (buf)
+ StringBuilder buf = new StringBuilder();
+ for (int i = first; i <= last; i++)
{
- for (int i = first; i <= last; i++)
- {
- Object item = node.get(i);
- buf.append(itemValue(obj, item));
- }
- value = buf.toString();
+ Object item = node.get(i);
+ buf.append(itemValue(obj, item));
}
+ value = buf.toString();
}
}
Index: modules/jetty/src/main/java/org/mortbay/xml/XmlParser.java
===================================================================
--- modules/jetty/src/main/java/org/mortbay/xml/XmlParser.java (revision 2256)
+++ modules/jetty/src/main/java/org/mortbay/xml/XmlParser.java (working copy)
@@ -669,12 +669,9 @@
*/
public synchronized String toString(boolean tag)
{
- StringBuffer buf = new StringBuffer();
- synchronized (buf)
- {
- toString(buf, tag);
- return buf.toString();
- }
+ StringBuilder buf = new StringBuilder();
+ toString(buf, tag);
+ return buf.toString();
}
/* ------------------------------------------------------------ */
@@ -692,7 +689,7 @@
}
/* ------------------------------------------------------------ */
- private synchronized void toString(StringBuffer buf, boolean tag)
+ private synchronized void toString(StringBuilder buf, boolean tag)
{
if (tag)
{
Index: modules/jetty/src/main/java/org/mortbay/io/BufferUtil.java
===================================================================
--- modules/jetty/src/main/java/org/mortbay/io/BufferUtil.java (revision 2256)
+++ modules/jetty/src/main/java/org/mortbay/io/BufferUtil.java (working copy)
@@ -315,7 +315,7 @@
if (bytes!=null)
return new String(bytes,buffer.getIndex(),buffer.length(),StringUtil.__ISO_8859_1);
- StringBuffer b = new StringBuffer(buffer.length());
+ StringBuilder b = new StringBuilder(buffer.length());
for (int i=buffer.getIndex(),c=0;c<buffer.length();i++,c++)
b.append((char)(0x7f&buffer.peek(i)));
return b.toString();
Index: modules/jetty/src/main/java/org/mortbay/io/AbstractBuffer.java
===================================================================
--- modules/jetty/src/main/java/org/mortbay/io/AbstractBuffer.java (revision 2256)
+++ modules/jetty/src/main/java/org/mortbay/io/AbstractBuffer.java (working copy)
@@ -495,7 +495,7 @@
public String toDetailString()
{
- StringBuffer buf = new StringBuffer();
+ StringBuilder buf = new StringBuilder();
buf.append("[");
buf.append(super.hashCode());
buf.append(",");
Index: modules/jetty/src/main/java/org/mortbay/resource/Resource.java
===================================================================
--- modules/jetty/src/main/java/org/mortbay/resource/Resource.java (revision 2256)
+++ modules/jetty/src/main/java/org/mortbay/resource/Resource.java (working copy)
@@ -432,7 +432,7 @@
String decodedBase = URIUtil.decodePath(base);
String title = "Directory: "+decodedBase;
- StringBuffer buf=new StringBuffer(4096);
+ StringBuilder buf=new StringBuilder(4096);
buf.append("<HTML>
Other Jetty examples (source code examples)Here is a short list of links related to this Jetty java5.patch source code file: |
| ... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.