Categories
discuss

Access Resources in Unit Tests

I’m using JUnit 4, Java 8, and Gradle 1.12. I have a file with default json that I need to load. My project has src/main/java/ (containing the project source), src/main/resources/ (empty), src/test/java/ (unit test source), and src/test/resources/ (the json data file to load) directories. The build.gradle file is in the root.

In my code I have:

public class UnitTests extends JerseyTest
{
  @Test
  public void test1() throws IOException
  {
    String json = UnitTests.readResource("/testData.json");
    // Do stuff ...
  }

  // ...
  private static String readResource(String resource) throws IOException
  {
    // I had these three lines combined, but separated them to find the null.
    ClassLoader c = UnitTests.class.getClassLoader();
    URL r = c.getSystemResource(resource); // This is returning null. ????
    //URL r = c.getResource(resource); // This had the same issue.
    String fileName = r.getFile();
    try (BufferedReader reader = new BufferedReader(new FileReader(fileName)))
    {
      StringBuffer fileData = new StringBuffer();
      char[] buf = new char[1024];
      int readCount = 0;
      while ((readCount = reader.read(buf)) != -1)
      {
        String readData = String.valueOf(buf, 0, readCount);
        fileData.append(readData);
      }

      return fileData.toString();
    }
  }
}

From what I read, that should give me access to the resource file. However, I get a null pointer exception when I try to use the URL, because the getSystemResource() call returns null.

How do I access my resource files?

Answer

Resource names don’t start with a slash, so you’ll need to get rid of that. The resource should preferably be read with UnitTests.getClassLoader().getResourceAsStream("the/resource/name"), or, if a File is required, new File(UnitTests.getClassLoader().getResource("the/resource/name").toURI()).

On Java 8, you could try something like:

URI uri = UnitTests.class.getClassLoader().getResource("the/resource/name").toURI();
String string = new String(Files.readAllBytes(Paths.get(uri)), Charset.forName("utf-8"));
Categories
discuss

Android queryIntentActivities always return empty list

I’m trying to get a list of all applications that are capable of sending text messages.

I found several solutions on that suggest to use the PackageManager.

I think that the Intent to be used is ACTION_SEND, but when i run my code i always receive an empty List.

This is my code:

        Intent mainIntent = new Intent(Intent.ACTION_SEND, null);
        List<ResolveInfo> pkgAppsList = getApplicationContext().getPackageManager().queryIntentActivities( mainIntent, PackageManager.GET_RESOLVED_FILTER);
        int size = pkgAppsList.size();
        int i = 0;
        Log.i(TAG, "Size: " + size);
        for(ResolveInfo infos : pkgAppsList){
            String name = infos.activityInfo.applicationInfo.loadLabel(getPackageManager()).toString();
            Log.i(TAG, "name: " + name);
        }

Any idea?

Answer

You haven’t set the MIME type for the Intent. For example:

mainIntent.setType("text/plain");

That will produce results. However, be mindful that this won’t exactly return “applications capable of sending text messages”, rather those that can accept a text, not necessarily for the purpose of sending a message (as an example, the Google Translate app is capable of receving text).

Categories
discuss

HOWTO handle 404 exceptions globally using Spring MVC configured using Java based Annotations

I am building a Spring 4 MVC app. And it is completely configured using Java Annotations. There is no web.xml. The app is configured by using instance of AbstractAnnotationConfigDispatcherServletInitializer and WebMvcConfigurerAdapter like so,

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"com.example.*"})
@EnableTransactionManagement
@PropertySource("/WEB-INF/properties/application.properties")
public class WebAppConfig extends WebMvcConfigurerAdapter {
...
}

and

public class WebAppInitializer extends
    AbstractAnnotationConfigDispatcherServletInitializer {
...
}

I am now trying to add a global/catch-all exception handler for 404 pages i.e. HttpStatus.NOT_FOUND but no success. Below are some of the ways I tried.

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException;

@ControllerAdvice
public class GlobalExceptionHandlerController {

    @ExceptionHandler
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public ModelAndView handleException (NoSuchRequestHandlingMethodException ex) {
            ModelAndView mav = new ModelAndView();
            return mav;
    }

    @ExceptionHandler
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public ModelAndView handleExceptiond (NoHandlerFoundException ex) {
            ModelAndView mav = new ModelAndView();
            return mav;
    }

    @ResponseStatus(HttpStatus.NOT_FOUND)
    @ExceptionHandler(NoHandlerFoundException.class)
    public void handleConflict() {

    }

    @ResponseStatus(HttpStatus.NOT_FOUND)
    @ExceptionHandler(NoSuchRequestHandlingMethodException.class)
    public void handlesdConflict() {
    }

}

None of these methods get executed. I am at a loss as to how to handle this. I do not want to use web.xml becasue then I would have to create one just for this.

Answer

By default, the DispatcherServlet does not throw a NoHandlerFoundException. You need to enable that.

The AbstractAnnotationConfigDispatcherServletInitializer should let you override how the DispatcherServlet is created. Do that and call

DispatcherServlet dispatcherServlet = ...; // might get it from super implementation
dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
Categories
discuss

Play/Pause Button HTML5 Audio

I’m trying to get HTML5 Audio to play/pause in one button. How would I possibly go around doing this? So the play button switches to the pause icon which is font awesome ‘fa fa-pause’ The code is here:

<audio id="myTune">
<source src="http://96.47.236.72:8364/;">
</audio>
<div class="btn-group btn-group-xs">
<a href="javascript:void(0)" class="btn btn-default" data-toggle="tooltip" title="Preview"     onclick="document.getElementById('myTune').play()"><i class="fa fa-play"></i></a>

Thank you!

Answer

You can put an id to the <i> tag and assign the fa fa-pause class when change of state:

<a href="javascript:void(0)" class="btn btn-default" data-toggle="tooltip" title="Preview" onclick="aud_play_pause()"><i id="stateicon" class="fa fa-play"></i></a>

<script>
  function aud_play_pause() {
    var myAudio = document.getElementById("myTune");
    if (myAudio.paused) {
      $('#stateicon').removeClass('fa fa-play');
      $('#stateicon').addClass('fa fa-pause');
      myAudio.play();
    } else {
      $('#stateicon').removeClass('fa fa-pause');
      $('#stateicon').addClass('fa fa-play');
      myAudio.pause();
   }
 }

Hope this helps

Categories
discuss

Jersey not obeying response media type rules from @Produces

I may be misinterpreting the Jersey specification for the media type of a response when a method can produce one of several. According to https://jersey.java.net/documentation/latest/jaxrs-resources.html#d0e1785, I think that when two media types listed in an @Produces(..) annotation match the incoming Accept header, Jersey will honor any weights associated with those types in the annotation or will pick the first if the weights do not decide a winner.

The code below demonstrates how this is not the behavior in practice. In the final two cases, I expect a JSON response when the request is ambiguous but I get XML instead. Is my understanding of the documentation incorrect? Or is this possibly a defect in Jersey?

Things I have tried:

  1. Remove the @XmlRootElement annotation from the model. The final two cases then pass but the 2nd case diverges because there is no suitable writer.
  2. Return Object from the resource method. Result is no change in the pass/fail status of the cases.
  3. Remove the weights from the @Produces(..) annotation of the resource class (JSON media type is still listed first). Result is no change in the pass/fail status of the cases.

This example is built using Jersey 2.10 and Java 1.8_05 on Ubuntu 14.04.

package demo;

import java.net.URI;
import java.util.Arrays;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.xml.bind.annotation.XmlRootElement;

import org.glassfish.jersey.jdkhttp.JdkHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;

import com.sun.net.httpserver.HttpServer;

public class DemonstrateAmbiguousMediaType {

    private static final String BASE_URI = "http://localhost:8092/";

    public static void main(final String[] args) {

        final HttpServer server = startServer();

        try {

            /*
             * These cases work fine.
             */
            check("application/json", "application/json");
            check("application/xml", "application/xml");

            /*
             * These cases should pass according to Jersey
             * documentation for @Produces
             * https://jersey.java.net/documentation/latest/jaxrs-resources.html#d0e1785
             * but they do not.
             */
            check("application/json", "application/*");
            check("application/json", "*/*");

        } finally {
            server.stop(0);
        }

    }

    private static void check(final String expected, final String... acceptTypes) {

        final MediaType atype = fetchAs(acceptTypes).getMediaType();
        final String actual = atype.getType() + "/" + atype.getSubtype();

        System.out.println(Arrays.asList(acceptTypes) + ":"
            + (expected.equals(actual) ? "pass" : "fail"));

    }

    private static Response fetchAs(final String[] acceptable) {

        return ClientBuilder.newClient()
                            .target(BASE_URI)
                            .path("model")
                            .request()
                            .accept(acceptable)
                            .get();

    }

    private static HttpServer startServer() {
        final ResourceConfig config = new ResourceConfig(Resource.class);
        final HttpServer rval = JdkHttpServerFactory.createHttpServer(
                URI.create(BASE_URI), config, false);
        rval.setExecutor(Executors.newCachedThreadPool(new ThreadFactory() {

            @Override
            public Thread newThread(Runnable r) {
                final Thread rval = new Thread(r);
                rval.setDaemon(true);
                return rval;
            }
        }));
        rval.start();
        return rval;
    }

    @XmlRootElement
    public static class Model {

        public int a = 10;
        public String b = "Bbb";

    }

    @Path("/model")
    @Produces({ "application/json; q=0.9", "application/xml; q=0.5" })
    public static class Resource {

        @GET
        public Model getModel() {
            return new Model();
        }

    }

}

Answer

I mis-read the specification. In @Produces(..) annotations, the quality parameter name is qs not q. When the quality parameters are specified correctly, all cases above pass.

When the quality parameters are removed, however, the final cases do not pass. According to that same Jersey documentation, the first listed should be chosen but it is not.

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..