Categories
discuss

Synchronized block: are variables “inside” other variables updated

Sorry for the non-technical title, but I think it summarizes my question well. If I interpret what I’ve read correctly, the synchronized block (apart from other consequences) will make all variables updated to/from the main memory (even those which are not accessed explicitly inside the synchronized block, only their “parent”?). E.g. quoting the answer of this stackoverflow question (I took it out of context, I’ll return to it later):

The memory barrier applies to all memory references, even unrelated ones.

I need confirmation whether I interpret this correctly. I’ve 2 threads (threadA, threadB). Consider the following code:

public class SomeClass {

private final Object mLock = new Object();
private int[] anArray;

public void initA() {
  synchronized(mLock) {
     ...
     anArray = new int[...];
     operationA();
  }
}

public void operationA() {
  synchronized(mLock) {
      // Manipulating the ELEMENTS of anArray,
      // e.g. in loops, etc.
      anArray[i] = ...
  }
}

public int[] getterB() {
   synchronized(mLock) {
      return anArray;   
   }
}
}

getterB() is called from ThreadB, initA() and operationA() are called from ThreadA. (Note that initA() is called even before ThreadB is created, so only getterB() and operationA() are concurrent.) Also note that I’ve a good reason not to return a copy of the array in getterB() (no, threadB doesn’t want to change its elements; the reason is an external requirement for my software that is not relevant now).

threadB does this:

int[] anArray = aSomeClass.getterB(); // aSomeClass is an instance of SomeClass
if (anArray[i] == n) { ....... } // various operations
...
//  various other operations that read the elements of anArray

As you can see, in getterB(), only the anArray reference is accessed within the memory barriers, and not the array values themselves. My questions:

  1. Will threadB see the most up-to-date array element values? (i.e. are the elements themselves updated too from main memory in getterB()?)

  2. The quoted statement mentioned that unrelated cached copies are updated from main memory too. I am not 100% how to intepret this unrelated (unrelated to the variable used for locking? or unrelated to the entire synchronized block?). I know I took the quote out of context, and since it’s a different stackoverflow question, I’ve added a comment there. So I appreciate if that question of mine is answered there (or here — I don’t care).

  3. Is there any difference in the answer if anArray is an array of Objects (and not of primitive types)? Going even further, what if it’s not an array, but a class that contains references to other classes? (i.e. an object that refers to other objects, and I access the contained objects through the object returned by getterB()). Will threadB use up-to-date copies of these contained references, or may it use its own local cached copies (since getterB() only updated their container object, but not the contained references themselves)?.

Answer

Taking your questions in order:

  1. Yes: You can safely assume that all of the values modified from any previously-called operationA() will be “up-to-date” in the array referenced by the result of getterB().

  2. I’ll let that be answered in the other link; I confess that I did not read that link yet. But my understanding is that all pending memory write-backs will “effectively” happen as you both enter and exit a synchronized block (although the details of how this happens — i.e., the efficiency of this, and whether there are more caching/pipelining “tricks” going on to make it appear that way — will depend on the hardware and compiler). If you want more details about this, I once found this link useful: http://www.infoq.com/articles/memory_barriers_jvm_concurrency

  3. No, there’s no difference (given what I wrote in answer 2).

Finally, just a comment that I would be very wary of your code as summarized above because of the fact that getterB() does not return a copy of the array. I understand that you have your reasons for doing it in the above way (and that you didn’t want this sort of feedback!), but you should be sure to understand that all of the “various operations” in thread B on anArray that occur after getterB() has returned will not be protected. (In other words, there will be hazards with any changes to the array made on thread A during this time.) One alternative that would avoid an inefficient deep array copy is to move these “various operations” within a synchronized block within a new method in SomeClass and get rid of getterB() entirely. Of course, I realize that the “right solution” in your code is dependent on many things not shown here, so feel free to ignore this bit.

Categories
discuss

“No resource methods” when using JAX-RS on TomEE+

Using stock TomEE+, I cannot get a simple JAX-RS resource to work. I constantly get an error of:

Jun 30, 2012 5:09:59 PM org.apache.cxf.jaxrs.utils.ResourceUtils checkMethodDispatcher
WARNING: No resource methods have been found for resource class com.tensorwrench.test.BaseResource
Jun 30, 2012 5:09:59 PM org.apache.cxf.jaxrs.utils.ResourceUtils checkMethodDispatcher
WARNING: No resource methods have been found for resource class com.tensorwrench.test.BaseResource
Jun 30, 2012 5:09:59 PM org.apache.cxf.jaxrs.utils.ResourceUtils checkMethodDispatcher
WARNING: No resource methods have been found for resource class com.tensorwrench.test.BaseResource
Jun 30, 2012 5:09:59 PM org.apache.cxf.jaxrs.AbstractJAXRSFactoryBean checkResources 
SEVERE: No resource classes found
Jun 30, 2012 5:09:59 PM org.apache.catalina.startup.HostConfig deployWAR
SEVERE: Error deploying web application archive D:workspaceapisrcmaincatalina_basewebappstestapi-1.0.war
org.apache.cxf.service.factory.ServiceConstructionException
                at org.apache.cxf.jaxrs.JAXRSServerFactoryBean.create(JAXRSServerFactoryBean.java:194)
                at org.apache.openejb.server.cxf.rs.CxfRsHttpListener.deploy(CxfRsHttpListener.java:126)
                at org.apache.openejb.server.cxf.rs.CxfRsHttpListener.deployPojo(CxfRsHttpListener.java:97)
                at org.apache.openejb.server.rest.RESTService.deployPojo(RESTService.java:270)
                at org.apache.openejb.server.rest.RESTService.afterApplicationCreated(RESTService.java:173)
                at org.apache.tomee.webservices.TomeeJaxRsService.afterApplicationCreated(TomeeJaxRsService.java:55)
                at org.apache.tomee.catalina.WebDeploymentListeners.afterApplicationCreated(WebDeploymentListeners.java:38)
                at org.apache.tomee.catalina.TomcatWebAppBuilder.afterStart(TomcatWebAppBuilder.java:818)
                at org.apache.tomee.catalina.GlobalListenerSupport.lifecycleEvent(GlobalListenerSupport.java:103)
                at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119)
                at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
                at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:401)
                at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:168)
                at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:895)
                at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:871)
                at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:615)
                at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:962)
                at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1603)
                at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
                at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
                at java.util.concurrent.FutureTask.run(FutureTask.java:138)
                at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
                at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
                at java.lang.Thread.run(Thread.java:662)
Caused by: javax.ws.rs.WebApplicationException
                at org.apache.cxf.jaxrs.AbstractJAXRSFactoryBean.checkResources(AbstractJAXRSFactoryBean.java:312)
                at org.apache.cxf.jaxrs.JAXRSServerFactoryBean.create(JAXRSServerFactoryBean.java:144)
                ... 23 more

Resource class: package com.tensorwrench.test;

import javax.ws.rs.*;
import javax.ws.rs.core.Response;
@Path("/test")
public class BaseResource {
  @GET @Produces("text/plain") @Path("test") Response helloWorld() {
    return Response.ok("Hello world","plain/text").build();
  }
  @GET @Produces("text/plain") String helloWorld2() {
    return "Hello world without path!";
  }
}

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="api" version="3.0" 
     xmlns="http://java.sun.com/xml/ns/j2ee" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_3_0.xsd">
<display-name>Service</display-name>

build.gradle:

apply plugin: 'java'
apply plugin: 'war'

repositories { mavenCentral() }

dependencies {
    providedCompile 'org.apache.openejb:javaee-api:6.0-4'
}

version = '1.0'
jar {
        manifest {
                attributes 'Title': 'Services',
                                     'Version': version
        }
}

</web-app>

I’ve tried a number of permutations, adding beans.xml, removing, changing order of the annotations, using different compile dependencies for the Java EE classes. I consistently get this error.

Answer

It looks like your resource methods are not public in scope. Try this:

import javax.ws.rs.*;
import javax.ws.rs.core.Response;
@Path("/test")
public class BaseResource {
  @GET @Produces("text/plain") @Path("test") public Response helloWorld() {
    return Response.ok("Hello world","plain/text").build();
  }
  @GET @Produces("text/plain") public String helloWorld2() {
    return "Hello world without path!";
  }
}
Categories
discuss

Why doesn’t the light in this scene work?

I wrote a game class with coffeescript that displays a plain and a rotating cube. You can see the code here: http://jsfiddle.net/6eRzt/6/

All is dandy, except for two things:

1) I have to do an ugly hack to get the requestAnimationFrame callback working:

var sh = new App();
sh.start();

function animate() {
    sh.animate();
    requestAnimationFrame(animate);
}

animate();​

2) This is my major concern: The SpotLight does not work. I tried to replicate the behavior from another JSFiddle (referenced in this Question), but without success. Maybe it’s just a stupid typo, or maybe I’m doing it wrong.

Plus: Am I on the wrong track with my App class? All the three.js examples I found so far use plain functions to get stuff running.

Answer

Regarding your major concern, you need to use WebGLRenderer instead of CanvasRenderer.

Fiddle: http://jsfiddle.net/6eRzt/10/

EDIT: There are a lot of ways of addressing your first concern. Everyone will have his own opinion.

Here is how I would do it. The closure keeps the variables from polluting the global namespace; there is no need for all of your this references.

Fiddle #2: http://jsfiddle.net/6eRzt/11/

Categories
discuss

HTTP doesn’t work in Android emulator

I tried multiple HTTP classes (HttpURLConnection, HTTPClient and others) but they don’t work in emulator. Then I decided to test that on my phone and it worked well!

So how can I fix this strange behaviour of Android emulator that HTTP classes don’t work (while browser can work)? They crash an application at all.

Here is my code:

public static SimpleXML getResponse(String action, Map<String, String> params) {
     // Create a new HttpClient and Post Header
    HttpClient httpclient = new DefaultHttpClient();
    HttpPost httppost = new HttpPost(action);

    try {
        // Add your data
        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(params.size());
        for(Map.Entry<String, String> heh : params.entrySet())
            nameValuePairs.add(new BasicNameValuePair(heh.getKey(), heh.getValue()));
        httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

        // Execute HTTP Post Request
        HttpResponse response = httpclient.execute(httppost);
        return SimpleXML.loadXml(response.getEntity().getContent());       

    } catch (ClientProtocolException e) {
        return null;
    } catch (IOException e) {
        return null;
    }   
}

LogCat log:

06-30 22:07:28.972: E/AndroidRuntime(682): FATAL EXCEPTION: main
06-30 22:07:28.972: E/AndroidRuntime(682): android.os.NetworkOnMainThreadException
06-30 22:07:28.972: E/AndroidRuntime(682):  at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
06-30 22:07:28.972: E/AndroidRuntime(682):  at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
06-30 22:07:28.972: E/AndroidRuntime(682):  at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
06-30 22:07:28.972: E/AndroidRuntime(682):  at java.net.InetAddress.getAllByName(InetAddress.java:214)
06-30 22:07:28.972: E/AndroidRuntime(682):  at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137)
06-30 22:07:28.972: E/AndroidRuntime(682):  at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
06-30 22:07:28.972: E/AndroidRuntime(682):  at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
06-30 22:07:28.972: E/AndroidRuntime(682):  at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
06-30 22:07:28.972: E/AndroidRuntime(682):  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
06-30 22:07:28.972: E/AndroidRuntime(682):  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
06-30 22:07:28.972: E/AndroidRuntime(682):  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
06-30 22:07:28.972: E/AndroidRuntime(682):  at net.ekvium.air.API.getResponse(API.java:98)
06-30 22:07:28.972: E/AndroidRuntime(682):  at net.ekvium.air.MainActivity$1.onClick(MainActivity.java:62)
06-30 22:07:28.972: E/AndroidRuntime(682):  at android.view.View.performClick(View.java:4084)
06-30 22:07:28.972: E/AndroidRuntime(682):  at android.view.View$PerformClick.run(View.java:16966)
06-30 22:07:28.972: E/AndroidRuntime(682):  at android.os.Handler.handleCallback(Handler.java:615)
06-30 22:07:28.972: E/AndroidRuntime(682):  at android.os.Handler.dispatchMessage(Handler.java:92)
06-30 22:07:28.972: E/AndroidRuntime(682):  at android.os.Looper.loop(Looper.java:137)
06-30 22:07:28.972: E/AndroidRuntime(682):  at android.app.ActivityThread.main(ActivityThread.java:4745)
06-30 22:07:28.972: E/AndroidRuntime(682):  at java.lang.reflect.Method.invokeNative(Native Method)
06-30 22:07:28.972: E/AndroidRuntime(682):  at java.lang.reflect.Method.invoke(Method.java:511)
06-30 22:07:28.972: E/AndroidRuntime(682):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
06-30 22:07:28.972: E/AndroidRuntime(682):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
06-30 22:07:28.972: E/AndroidRuntime(682):  at dalvik.system.NativeStart.main(Native Method)

Answer

If you look at this Android documentation, it explains

NetworkOnMainThreadException:

The exception that is thrown when an application attempts to perform a networking operation on its main thread.

This is only thrown for applications targeting the Honeycomb SDK or higher. Applications targeting earlier SDK versions are allowed to do networking on their main event loop threads, but it’s heavily discouraged.

So, depending on OS version, there may be enforcement (exception throwing) of the policy that you not make network requests on the UI thread. This could explain why your code works on a device, and not on an emulator (if they have different Android versions).

You could change the ThreadPolicy. But as an alternative, I’d suggest you look again at the statement in the Android docs. They heavily discourage performing network operations on the main thread, and I’d certainly agree with them.

So, rather than changing the policy to make it legal, you might consider changing your code, so that your getResponse() method is not called on the UI thread.

Typically, you would use AsyncTask to do the work in the background.

Categories
discuss

Adding border to a merged region in POI XSSF workbook

I’m using apache poi 3.7 and I need to put border to a range of cells or merged region.

how can I to apply border to a merged region when the sheet and workbook type is XSSF. In HSSF type I use RegionUtil-/HSSFRegionutil, but if use the first object (Regionutil) in XSSF type its doesn’t works and puts a black background color to the range of cells.

Regionutil ussually works with CellRangeAddress and i don’t find information about this trouble. I don’t know if the CellRangeAddres causes this.

Answer

In order to do this, you have to add a blank cell to every cell in the merged region, then add the appropriate borders to each cell. For example, the following code will create a merged region of 5 cells in the same row, with a border around the whole merged region, and the text centred in the region.

XSSFWorkbook wb = new XSSFWorkbook();
CellStyle borderStyle = wb.createCellStyle();
borderStyle.setBorderBottom(CellStyle.BORDER_THIN);
borderStyle.setBorderLeft(CellStyle.BORDER_THIN);
borderStyle.setBorderRight(CellStyle.BORDER_THIN);
borderStyle.setBorderTop(CellStyle.BORDER_THIN);
borderStyle.setAlignment(CellStyle.ALIGN_CENTER);
Sheet sheet = wb.createSheet("Test Sheet");
Row row = sheet.createRow(1);
for (int i = 1; i <= 5; ++i) {
    Cell cell = row.createCell(i);
    cell.setCellStyle(borderStyle);
    if (i == 1) {
        cell.setCellValue("Centred Text");
    } 
}
sheet.addMergedRegion(new CellRangeAddress(1, 1, 1, 5));
Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..