Clayton Cramer

Ranch Hand
+ Follow
since Aug 26, 2010
Merit badge: grant badges
For More
Cows and Likes
Cows
Total received
0
In last 30 days
0
Total given
0
Likes
Total received
0
Received in last 30 days
0
Total given
1
Given in last 30 days
0
Forums and Threads
Scavenger Hunt
expand Ranch Hand Scavenger Hunt
expand Greenhorn Scavenger Hunt

Recent posts by Clayton Cramer

I am cleaning up the worst software mess that I have seen in 35 years in this industry. I do not have the option of burning this code down (which would be too merciful for it) and starting over.

There are several JSPs that share some forms, but not others. The first of these, w_psi_s1_11.jsp (great name, what?) has access to offenderEmploymentForm. From this JSP, we call an action method OffenderEmployment.editEmployer. This action method transfers control to w_psi_s1_16.jsp (another great name), which has access to offenderEmploymentForm and employerSearchForm. The user hits the add button, which does a submit over to action method OffenderEmploymentAction.findEmployer. (Yes, the class is not the same as the other action method that I have already mentioned.) The findEmployer action method transfers control to w_psi_s1_14.jsp, where the user gets to add a new employer to the list. This JSP also has access to offenderEmploymentForm -- however, the action method that it calls on save, EmployerAction.save, does not have access to offenderEmploymentForm.

The problem is that when the submit on this last JSP happens, I need to update the employerId field in offenderEmploymentForm. I have the employerId visible in the JSP, but it does no good to pass it to the EmployerAction.save action method, because that class does not have access to the session form offenderEmploymentForm. I can read offenderEmploymentForm.employerId from the JSP -- but how do I write it from the JSP?

I have looked at a variety of methods around this. I thought that I could pass the offenderEmploymentForm using setAttribute in the JSP and getAttribute in the EmployerAction.save method -- but no, Struts 1 can't pass objects, and I really need to to update the existing session offenderEmploymentForm.

Help me, Mr. Wizard!
10 years ago
It is certainly the case that we have vast numbers of i + "" expressions scattered about the code, and that might explain why we have 26 MB of "". Each new StringBuilder("") would presumably create a distinct copy, because a StringBuilder object is mutable.
11 years ago
We have started to use a tool called Your Kit Java Profiler. It shows something that just dumbfounds me, because I would have thought Java was smarter than this. It shows that we have 26 MB of heap devoted to duplicate copies of the empty string "". Unlike every C compiler that I have ever, used it would appear that if you have multiple strings that are identical, and immutable (you are referencing them as "" in expressions like str = i + ""), each reference produces its own copy of that empty string. The painful solution is to define an empty string in one file:

public final static String s = "";

and then replace all the "" references with s.

Is there really no way to tell the Java compiler to combine immutable constants?
11 years ago

Martin Vajsar wrote:Are you sure the database field is declared as a character (that is, not binary) type?

Java uses Unicode internally, so it's the JDBC driver's responsibility to handle character set conversions to match the database's character set. I'm not aware of any method that would allow you messing with that.

A quick search brought up some results that mentioned character set conversion bugs in JDBC drivers.



Yes, it is declared as CHAR(30). It looks like DB_LOCALE and CLIENT_LOCALE are properties associated with the database connection, and this is likely the problem: under Windows, this is CP1252; under Linux, it defaults to UTF-8 or the ISO equivalent. I probably need to force the connection to CP1252, but I have not figured out how to do that yet.
I am running into an annoying problem. I have an application that under Windows retrieves strings from a database and the strings are what I would expect: 7-bit ASCII. Under Linux, the same application, talking to the same database, sometimes returns 8-bit ASCII. The particular symptom is that spaces, instead of being x'20', are x'a0' instead under Linux. My guess is that there is some method or setting for ResultSet or CallableStatement that says, "force all 8-bit character values to 7-bits" but I can't find it.

Tim Holloway wrote:The actual debugger is built into each JVM instance. What Eclipse is providing is simply a client to communicate with that debugger via a network connection (the Java JDK also comes with a command-line-based debug client app). So whatever your debugger sees will be relative to what the remote application sees, not what's on your debug console machine.

Do note, however, that use of relative paths in J2EE is a great way to get into trouble, debugger or not. So make sure that A) your file paths are absolute and B) The tomcat server instance userid has the necessary filesystem access rights.


I am using an absolute path to a file name, and that file exists, and is readable. Mystifying. I notice that when I call the File.exists method for the path, the File.exists method calls a getBooleanAttributes method that has the attribute WinNTFileSystem.
11 years ago
I am starting to use MyEclipse to do remote debugging of a Tomcat7 application. It seems to work quite well...with one peculiar behavior.

The remote Tomcat7 application is running under Linux; MyEclipse is running on my PC. The problematic Java class attempts to open a file, and it is SUPPOSED to open it on the server. The problematic method is:



The problem is that file.exists() and file.canRead() are both returning false for a filePath that exists, and is readable. Curiously, when it executes File file = new File(filePath); , all the forward slashes in filePath are now \\, as though it thinks it is opening the file under Windows, and in the calling method, File.separator is \\, not /. I don't think this is just a matter of MyEclipse misdisplaying the file separators, because the File method is claiming that the file does not exist. Is there perhaps something that needs to be set somewhere to tell MyEclipse that when remote debugging, all file references are also remote?
11 years ago
It looked elegant. But I see that it is now somewhat obsolete. Worse, it does not seem to be terribly reliable, perhaps because it is no longer widely used. Or perhaps the other way around: perhaps it is no longer widely used because it is not terribly reliable.
11 years ago
I ask because I have been finding getting the Oracle Java RMI example working (reliably) astonishingly difficult -- and I can't find any recently published books on the subject. The absence of recently published books could mean that it is so simple that there is no need for them, but I also see that the problems that I am having about security appear in vast numbers of web pages.

So, is anyone developing any commercial products using Java RMI, or is everyone just using this for school projects?
11 years ago
I am writing a Java RMI application -- a really trivial one, and even this has been far more work than I expected. The server starts up, rebinds the name, then I start the client, and:

Java RMI Error unmarshaling return header; nested exception is:
java.io.EOFException

Where should I start looking for the cause of this? And what does this mean? The text of the error message suggests that there is a mismatch between the definition of the interface that is shared by the client and server. Am I guessing right on this? Or can someone point me in a better direction?
11 years ago
I found the answer over at http://patriot.net/~tvalesky/easyrmi.html. Here's an example that worked for me:

-Djava.security.policy=c:\rmi\hello\server.policy

Wow! Surprisingly simple!
11 years ago

Tim Holloway wrote:he one thing I can see that I'm not sure of is your URL. The proper syntax, I believe is: "file://C:/tomcat5/webapps/rmi/-". That extra slash after the protocol ID is critical, I believe.


It appears from reading http://docs.oracle.com/javase/1.4.2/docs/guide/rmi/codebase.html that file:/// (three slashes) is required.
11 years ago
This is very useful information! Thank you! What about in the server.policy file itself? Currently I have:

grant codeBase "file:///C:/tomcat5/webapps/rmi/-" {
permission java.security.AllPermission;
};

My suspicion is that since the server.policy file is referenced directly (not by a URL) that perhaps the codeBase parameter should also be just a file name. But that does not seem to work any better.
11 years ago
It is unfortunate that the error messages are not a bit more helpful. I have now tried my server.policy file with one, two, and three slashes after file:, and the results are:

One slash:

C:\Documents and Settings\ccramer\Workspaces\MyEclipse 9\rmi-server\src>java -Xd
ebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,address=8000,suspend=n -Dj
ava.rmi.server.logCalls=true -Dsun.rmi.loader.loglLevel=5 -Dsun.rmi.server.excep
tionTrace=true -Dsun.rmi.server.logLevel=5 -cp .;c:\tomcat5\webapps\rmi\compute.
jar -Djava.security.manager -Djava.rmi.server.codebase=file:/c:\tomcat5\webapps\
rmi\compute.jar -Djava.security.policy=file:/c:/tomcat5/webapps/rmi/server.polic
y engine.ComputeEngine
Listening for transport dt_socket at address: 8000
Oct 17, 2012 10:21:16 AM sun.rmi.server.UnicastRef newCall
FINE: main: get connection
ComputeEngine exception:
java.security.AccessControlException: access denied (java.net.SocketPermission 1
27.0.0.1:1099 connect,resolve)
at java.security.AccessControlContext.checkPermission(Unknown Source)
at java.security.AccessController.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkConnect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(Unknown S
ource)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(Unknown S
ource)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(Unknown Source)
at sun.rmi.transport.tcp.TCPChannel.createConnection(Unknown Source)
at sun.rmi.transport.tcp.TCPChannel.newConnection(Unknown Source)
at sun.rmi.server.UnicastRef.newCall(Unknown Source)
at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
at engine.ComputeEngine.main(ComputeEngine.java:36)

Two slashes:

identical

Three slashes:

identical

One would almost get the impression that it is not even seeing the server.policy file. Perhaps the problem is the -Djava.security.policy= parameter? I suppose that I can try changing the number of slashes there next. And I did, with one, two, and three slashes after file: on the command line arguments, without any change in behavior.
11 years ago
Okay, this helps. Let me ask you a more detailed questions:

"To test RMI in eclipse, you have to launch an RMI server from Eclipse OR you have to attach the Eclipse debugger to the RMI server as a remote debugging session (this requires the RMI server to be launched with debugging enabled so that it will open a network port for Eclipse to debug through)."

It appears that the magic incantation on the server command line arguments is:

-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,address=8000,suspend=n -Djava.rmi.server.logCalls=true -Dsun.rmi.loader.loglLevel=5 -Dsun.rmi.server.exceptionTrace=true -Dsun.rmi.server.logLevel=5

I am guessing on the logLevel values.

I am still running into the problem with

java.security.AccessControlException: access denied (java.net.SocketPermission 127.0.0.1:1099 connect,resolve)

This seems to be a security policy problem, which I still have not figured out. I am passing -Djava.security.policy=server.policy, where server.policy is the name of a file containing

grant codeBase "file:/C:/tomcat5/webapps/rmi/-" {
permission java.security.AllPermission;
};

Yes, I am not relying on Tomcat, but that's where the file is.

Should I specify a fully qualified path to where server.policy is located?
11 years ago