I wanted to see whether it works (yes), here's some quick code:
PDDocument doc = new PDDocument();
PDPage page = new PDPage();
doc.addPage(page);
page.setResources(new PDResources());
System.out.println(page.getResources());
Map<String, PDShading> shadings = new HashMap<>();
COSDictionary dict = new COSDictionary();
dict.setInt(COSName.SHADING_TYPE, 2);
dict.setName(COSName.COLORSPACE, "DeviceRGB");
COSArray coords = new COSArray();
coords.add(COSInteger.get(100));
coords.add(COSInteger.get(400));
coords.add(COSInteger.get(400));
coords.add(COSInteger.get(600));
dict.setItem(COSName.COORDS, coords);
COSDictionary fdict = new COSDictionary();
fdict.setInt(COSName.FUNCTION_TYPE, 2);
COSArray dom = new COSArray();
dom.add(COSInteger.get(0));
dom.add(COSInteger.get(1));
COSArray c0 = new COSArray();
c0.add(COSFloat.get("1"));
c0.add(COSFloat.get("0"));
c0.add(COSFloat.get("0"));
COSArray c1 = new COSArray();
c1.add(COSFloat.get("0.5"));
c1.add(COSFloat.get("1"));
c1.add(COSFloat.get("0.5"));
fdict.setItem(COSName.DOMAIN, dom);
fdict.setItem(COSName.C0, c0);
fdict.setItem(COSName.C1, c1);
fdict.setInt(COSName.N, 1);
PDFunctionType2 fun = new PDFunctionType2(fdict);
dict.setItem(COSName.FUNCTION, fdict);
PDShadingType2 shading = new PDShadingType2(dict);
shadings.put("sh1", shading);
page.getResources().setShadings(shadings);
PDPageContentStream contentStream = new
PDPageContentStream(doc, page, true, false);
contentStream.appendRawCommands("/sh1 sh");
contentStream.close();
doc.save("shtest.pdf");
doc.close();