How to handle deeply nested exception in struts2? - exception

My struts2 webapp makes use of a SQL database. Within the DB access code, I've written a basic try/catch handler that catches SQL or general exceptions, writes the detail to a log file, and then continues. The hierarchy of classes is as follows:
Action method -> get or set method on Model -> DB access.
//Action method in action class
public string doActionMethod() throws Exception
{
String results = SampleModel.getResults();
}
//Model method in model class
public string getResults() throws Exception
{
String results = DBLayer.runQuery("SELECT Results FROM SampleTable WHERE Value='1');
}
//Method that queries database in DB access class
public string runQuery() throws Exception
{
ResultSet rs = null;
Connection dbConnection = null;
PreparedStatement preparedStatement = null;
dbConnection = MSSQLConnection.getConnection();
preparedStatement = dbConnection.prepareStatement(sqlQuery);
//run SQL statements
return String(rs.get(0));
}
I'd like caught exceptions to bubble up to the Action level, so that I can forward them to an appropriate error page. Is there a better way to do this than adding a "throws Exception" to the method signature?

Since you have no hope of recovery, throw an application-specific RuntimeException.
Use standard Struts 2 declarative exception handling to get your app to the appropriate error page.

Related

How to read CSVRecord in apache beam?

I have a Java Iterable object, Iterable records. And I want to pass it to the Beam pipeline. I tried
PCollection csvRecordPC = p.apply("Create collection", Create.of(records));
It caused an error
An exception occured while executing the Java class. Can not determine a default Coder for a 'Create' PTransform that has no elements. Either add elements, call Create.empty(Coder), Create.empty(TypeDescriptor), or call 'withCoder(Coder)' or 'withType(TypeDescriptor)' on the PTransform.
Which Coder should I use? Or how can I write my custom coder?
I found a solution using FileIO.
p.apply(FileIO.match().filepattern(options.getInputFile()))
.apply(FileIO.readMatches())
.apply(ParDo.of(new CsvParser()))
The CsvPaser() is
public class CsvParser extends DoFn<ReadableFile, CSVRecord> {
#DoFn.ProcessElement
public void processElement(#Element ReadableFile element, DoFn.OutputReceiver<CSVRecord> receiver) throws IOException {
InputStream is = Channels.newInputStream(element.open());
Reader reader = new InputStreamReader(is);
Iterable<CSVRecord> records = CSVFormat.EXCEL.withFirstRecordAsHeader().parse(reader);
for (CSVRecord record : records) {
receiver.output(record);
}
}
}

Unable to mock URL class using PowerMockito/Mockito

I am trying to use PowerMockito to mock the creation of the java.net.URL class in my code that I'm testing. Basically, I want to prevent the real HTTP request from occurring and instead 1) check the data when the request is made and 2) supply my own test data back on a mocked response. This is what I'm trying:
#RunWith(PowerMockRunner.class)
#PrepareForTest({ URL.class, MockedHttpConnection.class })
public class Test {
URL mockedURL = PowerMockito.mock(URL.class);
MockedHttpConnection mockedConnection = PowerMockito.mock(MockedHttpConnection.class);
...
PowerMockito.whenNew(URL.class).withParameterTypes(String.class).withArguments("MyURLString").thenReturn(mockedURL);
PowerMockito.when(mockedURL.openConnection()).thenReturn(mockedConnection);
...
}
The code that I want to test looks like this:
URL wlInvokeUrl = new URL(wlInvokeUrlString);
connection = (HttpURLConnection) wlInvokeUrl.openConnection();
Earlier in my test scenario I mock the wlInvokeUrlString to match "MyURLString". I've also tried using various other forms of the whenNew line, trying to inject the mock. No matter what I try, it never intercepts the constructor. All I want to do is "catch" the call to openConnection() and have it return my mocked HTTP connection instead of the real one.
I have mocked other classes ahead of this one in the same script and these are working as expected. Either I need a second pair of eyes (probably true) or there is something unique about the URL class. I did notice that if I use "whenNew(URL.class).withAnyArguments()" and change the "thenReturn" to "thenAnswer" I could get it to trigger. Only problem is I never get the URL call for my code. What I see is an invocation of the 3-argument constructor for URL.class with all nulls for the parameters. Could it be this class is from the Java runtime and is bootstrapped by the test runner? Any help is much appreciated.
It's a common mistake when use PowerMockito.whenNew.
Note that you must prepare the class creating the new instance of MyClass for test, not the MyClass itself. E.g. if the class doing new MyClass() is called X then you'd have to do #PrepareForTest(X.class) in order for whenNew to work
From Powermock wiki
So, you need a bit change your test and add to #PrepareForTesta class which create a new instance of URLlike:
#RunWith(PowerMockRunner.class)
#PrepareForTest({ URL.class, MockedHttpConnection.class , ConnectionUser.class})
public class URLTest {
public class URLTest {
private ConnectionUser connectionUser;
#Before
public void setUp() throws Exception {
connectionUser = new ConnectionUser();
}
#Test
public void testName() throws Exception {
URL mockedURL = PowerMockito.mock(URL.class);
MockedHttpConnection mockedConnection = PowerMockito.mock(MockedHttpConnection.class);
PowerMockito.whenNew(URL.class).withParameterTypes(String.class).withArguments("MyURLString").thenReturn(mockedURL);
PowerMockito.when(mockedURL.openConnection()).thenReturn(mockedConnection);
connectionUser.open();
assertEquals(mockedConnection, connectionUser.getConnection());
}
}
where:
public class ConnectionUser {
private String wlInvokeUrlString = "MyURLString";
private HttpURLConnection connection;
public void open() throws IOException {
URL wlInvokeUrl = new URL(wlInvokeUrlString);
connection = (HttpURLConnection) wlInvokeUrl.openConnection();
}
public HttpURLConnection getConnection() {
return connection;
}
}
I'm not sure the difference between .withParameterTypes(x) and .withArguments(x) but I believe you need to set it up as follows for your code to work. Give it a try and let me know if this doesn't help.
PowerMockito.when(mockedURL.openConnection()).thenReturn(mockedConnection);
PowerMockito.whenNew(URL.class).withArguments(Mockito.anyString()).thenReturn(mockedURL);
The problem is that the arguments of the real call are not matching with the expected in your mock.
PowerMockito.whenNew(URL.class).withParameterTypes(String.class).withArguments("MyURLString").thenReturn(mockedURL) will return mockedURL only the call is new URL("MyURLString").
If you change it to:
PowerMockito.whenNew( URL.class ).withParameterTypes( String.class )
.withArguments( org.mockito.Matchers.any( String.class ) ).thenReturn( mockedURL );
It will catch any string passed to the constructor URL(String) (even null) and return your mock.
When you tried
"whenNew(URL.class).withAnyArguments()" and change the "thenReturn" to
"thenAnswer" I could get it to trigger. Only problem is I never get
the URL call for my code. What I see is an invocation of the
3-argument constructor for URL.class with all nulls for the
parameters.
PowerMock will try to mock all constructors (org.powermock.api.mockito.internal.expectation.DelegatingToConstructorsOngoingStubbing.InvokeStubMethod at line 122) then it calls the first one (with 3 arguments) and mock its answer. But the subsequent calls will return the already mocked one because you told it to mock for any arguments. That's why you see just one call with null, null, null in your Answer.

Groovy SQL: Shall I manually close the Mysql connection

I have a grails service that calls stored procedures using Groovy SQL.
I am using dataSource for initializing the connection.
My question is: Do I need to manually close the connection or will it be handled by Groovy or GORM (since I am using def dataSource)?
Here is how my service is structured.
class MyService {
static transactional = Boolean.FALSE
private static final String STATEMENT_ONE_SQL = "{ call sp_One(?) }"
private static final String STATEMENT_TWO_SQL = "{ call sp_Two(?,?) }"
def dataSource
Sql sql
#PostConstruct
def initSql() {
sql = new Sql(dataSource)
}
List<GroovyRowResult> callSpOne(Integer id) {
List<GroovyRowResult> results = sql.rows(STATEMENT_ONE_SQL, [id])
return results
}
List<GroovyRowResult> callSpTwo(Integer id, String name) {
List<GroovyRowResult> results = sql.rows(STATEMENT_TWO_SQL, [id, name])
return results
}
Basing on official docs
Finally, we should clean up:
sql.close()
If we are using a DataSource and we haven't enabled statement caching, then strictly speaking the final close() method isn't required - as all connection handling is performed transparently on our behalf; however, it doesn't hurt to have it there as it will return silently in that case.
If instead of newInstance you use withInstance, then close() will be called automatically for you.

Byteman JUnit Runner - impossible to trigger IOException on auto-closed InputStream#close

I have got the following code:
Collection<String> errors = ...;
try (InputStream stream = My.class.getResourceAsStream(resource)) {
// do stuff
}
catch(IOException ex) {
errors.add("Fail");
}
I'm trying with Byteman Junit Runner to trigger an IOException when the (valid) input stream I give is supposedly closed:
#RunWith(BMUnitRunner.class)
public class MyTest {
private My my = new My();
#BMRule(
name = "force_read_error",
targetClass = "java.io.InputStream",
targetMethod = "close()",
action = "throw new IOException(\"bazinga\")"
)
#Test
public void catches_read_error() throws IOException {
Collection<String> errors = my.foo("/valid-resource-in-classpath");
assertThat(errors).containsExactly("Fail");
}
}
My test fails: errors is always empty, which means the Byteman rule obviously isn't executed (it's well loaded by the agent, so I don't understand what's going on).
How can I trigger an IOException on close method called via try-with-resources?
Your rule ist not firing, because the class of the stream object received when calling
InputStream stream = My.class.getResourceAsStream(resource)
is not a "java.io.InputStream" class. It is a class extending "java.io.InputStream", most likely a "BufferedInputStream".
To tell byteman to "trigger rule for any class extending java.io.InputStream", you need to put a '^' before the class name:
targetClass = "^java.io.InputStream"
This change might have the unwanted side effect, that the rule gets triggered also when other objects extending "java.io.InputStream" get closed. To prevent this from happening, a condition should be added to the rule to only get triggered, when the caller matches the "foo" method of the "My" class. Byteman has a helper method for that called "callerMatches" (Please see also the advanced tutorial)
A working condition for your case would be:
condition = "callerMatches(\".+My.foo\",true,true)"
The complete Byteman rule definition as BMRule annotation should look like:
#BMRule(
name = "force_read_error",
targetClass = "^java.io.InputStream",
targetMethod = "close()",
condition = "callerMatches(\".+My.foo\",true,true)",
action = "throw new java.io.IOException(\"bazinga\")"
)

Spring MVC Exceptions

I have the following code in the Controller class and for some reason although i have exception handling implemented as well as a try.....catch block i am still unable to capture my exceptions.
I am just executing a test, in the DAO class i change the sql string that inserts into the database to leave out a column just so the DAO will fail. The DAO class fails and the error is written to the logs however even thou the officerManager.RegisterOfficer(officer) was not successful the code goes on to return the model.addAttribute("results","Record Was Saved").
This is not accurate and i would like for the controller to throw an error. Under is the code.
Controller
#RequestMapping(value="officer_registration.htm", method=RequestMethod.POST)
public ModelAndView handleRequest(#Valid #ModelAttribute Officers officer,BindingResult result,ModelMap m,Model model,HttpServletRequest request,HttpServletResponse response)throws Exception{
try{
if(result.hasErrors()){
model.addAttribute("division", myDivision);
model.addAttribute("position", myPosition);
model.addAttribute("gender", myGender);
return new ModelAndView("officer_registration");
}else{
//check the request if its an update or an insert
String user_request = request.getParameter("user_request");
logger.info("The Users Request Was " + user_request);
if (user_request.equals("Save")){
officerManager.RegisterOfficer(officer);
model.addAttribute("results","Record Was Saved");
}else{
officerManager.UpdateOfficer(officer);
model.addAttribute("results","Record Was Updated");
}
model.addAttribute("division", myDivision);
model.addAttribute("position", myPosition);
model.addAttribute("gender", myGender);
return new ModelAndView("officer_registration");
}
}catch(Exception e ){
model.addAttribute("division", myDivision);
model.addAttribute("position", myPosition);
model.addAttribute("gender", myGender);
model.addAttribute("results","Error: Unable to Save Record!");
return new ModelAndView("officer_registration");
}
}
DAO
public void saveOfficer(Officers officer) {
logger.info("In saveOfficer");
//SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
try{
int count = getJdbcTemplate().update("INSERT INTO crimetrack.tblofficers (userName,password, fName, lName, oName, divisionNo, positionId, emailAdd, startDate, endDate, genderId,phoneNo, dob,badgeNo) "+
"VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
, new Object[]{officer.getUserName(),StringSecurity.EncryptString(officer.getPassword()),officer.getfName(),
officer.getlName(),officer.getoName(),officer.getDivisionNo(),officer.getPositionId(),
officer.getEmailAdd(),officer.getStartDate(),officer.getEndDate(),officer.getGenderId(),
officer.getPhoneNo(),officer.getDob(),officer.getBadgeNo()});
logger.info(count +" Rows affected in tblOfficers");
}catch(Exception e){
logger.error("Could not save officer ", e);
}
}
You're not allowing the error to bubble up back to the controller.
You're handling the exception within the DAO, in which case the method exits normally, and no exception is caught within the Controller.
Either don't surround the DAO with a try catch and let the exception bubble back to the controller (recommended), or catch and rethrow the exception (if you follow this route, throw as a RuntimeException, either create your own, or rethrow as a RuntimeException, that way you won't have to catch all the way through the call stack.)
Also, it's generally frowned upon to catch generic exception as it is tougher to nail down exactly what caused it unless you look within the logs. Knowing which exceptions to handle ahead of time is usually better practice.